There are no arguments that depend on a template parameter

C++Templates

C++ Problem Overview


I am trying to do the following:

template <class T>
std::ifstream& operator>> (std::ifstream& fin, List<T> l)
{
    T temp;
    l.resize(0);
    fin >> ignore(1,'\t');
    for(ListIterator<T> i=l.begin();i!=l.end();i++)
    {
        fin >> ignore(1,'\t') >> temp;
        l.push_back(temp);
    }
    return fin;
}

I have to read all the contents from a file. Each field is separated by '\t' character, so I have to ignore the '\t' characters.

The error log is the following:

/home/ramy/Documents/C++/Prova/Util.h||In functionstd::ifstream& Util::operator>> (std::ifstream&, Util::List<T>)’:|
/home/ramy/Documents/C++/Prova/Util.h|431|error: there are no arguments to ‘ignore’ that  depend on a template parameter, so a declaration of ‘ignore’ must be available|
/home/ramy/Documents/C++/Prova/Util.h|431|note: (if you use ‘-fpermissive’, G++ will  accept your code, but allowing the use of an undeclared name is deprecated)|
||=== Build finished: 1 errors, 0 warnings ===|

C++ Solutions


Solution 1 - C++

For builtin types, argument dependent lookup (ADL) is not performed, therefore, an ignore symbol must be "imported" into the current namespace.

You can, for example, do this; from most preferred to least preferred (i.e. to most intrusive and name polluting):

  • foobar::ignore (...)
  • using foobar::ignore; ignore(...);
  • using namespace foobar; ignore(...);

The error message comes up like this because in templates, you also enter the realm of dependent names and Two Phase Lookup. Names that depend on a template parameter, e.g.

template <typename T> void foo() {
    T x;
    x.frobnicate();
}

are looked up in phase 2, which is upon instantiation. Names that do not depend on template parameters, like

class Foo {};

template <typename T> void foo() {
    Foo foo;
    foo.frobnicate();
}

must be resolvable in the first phase.

This separation helps template authors to find bugs earlier and to find correct symbols, and it helps making templates more generic. For example, in C# generics, everything must be resolvable, which puts rather stringent limits on their flexibility (because everything that may be used by a generic must be defined). Oppositely, some old C++ compilers resolved in phase 2 only, i.e. at instantiation time, which had some subtle consequences for lookup and error finding.

The C++ 2-phase model combines the best of the eager-model (C#) and the lazy-model (some old C++ compilers).

Solution 2 - C++

For an easier answer, see https://web.archive.org/web/20130423054841/http://www.agapow.net/programming/cpp/no-arguments-that-depend-on-a-template-parameter

TL;DR: replace ignore() with this->ignore() and your problem will go away.

Solution 3 - C++

The error message means that there is no definition of ignore that the compiler can use at this point. It is exactly the same error that you get if you do:

void f() {
   g();
}
void g() {}

... even if it looks very different. Note that there is no ADL issue here as the other answers say. The reason that the error message is so convoluted is because of the way that templates are processed by the compiler.

Templates are processed in two passes, during the first pass everything that is not dependent on the instantiating type must be verified without performing the type substitution, during this pass every non-dependent name must be checked, and in this case the compiler has failed to resolve ignore with the declarations available at the place of definition of the template.

If the expression depended on the type arguments to the template, it would not need to be fully resolved during the first pass and it would be tried again after type substitution, with the declarations available at the place of instantiation.

Solution 4 - C++

I've had the same problem and I've fixed it by changing include order.

As phresnel says, the compiler cannot resolve that on the 1st phase, which in my case was because the header with the problematic template method was included before the one with the inner method that couldn't be resolved.

Adding the needed header include removed the error for me. Hope this helps someone else.

Solution 5 - C++

I don't know about the weather your problem is solved or not and I hope it would have.

Whenever I face the problem of "There are no arguments that depend on a template parameter" I override the method and call the parent class member function.

To show what I mean consider a class below which is template class ADT

template <typename DataTypeOfNode>
class LinearList
{
public:
	LinearList(){}
	void addAtBeg(DataTypeOfNode data) {
		//Inside implementation....
	}
	DataTypeOfNode removeFromFront() {
		//Inside implementation....
	} 

	// And many more useful methods
	~LinearList(){}
	
};

Now if you inherit this class with a base class say "PriorityQueue" like this

template <typename DataTypeOfNode>
class PriorityQueue : public LinearList<DataTypeOfNode>
{
public:

	void enqueue(DataTypeOfNode data){
		addAtBeg(data);
	}

	DataTypeOfNode dequeue(){
		return removeFromFront() ; 
	}
	PriorityQueue(){}
	~PriorityQueue(){}
};

After compliling you will get error like "There are no arguments that depend on a template parameter" for removeFromFront() and addAtBeg() methods becaouse they have template parameters.

To fix this error you just need to override these methods and call the parent class methods like this

template <typename DataTypeOfNode>
class PriorityQueue : public LinearList<DataTypeOfNode>
{
public:

	//Calling parent class methods

	void addAtBeg(DataTypeOfNode data){
		LinearList<DataTypeOfNode>::addAtBeg(data) ; 
	}

	DataTypeOfNode removeFromFront(){
		return LinearList<DataTypeOfNode>::removeFromFront() ; 
	}

	void enqueue(DataTypeOfNode data){
		addAtBeg(data);
	}

	DataTypeOfNode dequeue(){
		return removeFromFront() ; 
	}
	PriorityQueue(){}
	~PriorityQueue(){}
};

Solution 6 - C++

It means that ignore cannot be found by the compiler and ADL cannot kick in. This means that there is no suitably-scoped ignore function.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRamy Al ZuhouriView Question on Stackoverflow
Solution 1 - C++Sebastian MachView Answer on Stackoverflow
Solution 2 - C++John HainsworthView Answer on Stackoverflow
Solution 3 - C++David Rodríguez - dribeasView Answer on Stackoverflow
Solution 4 - C++Xavier Arias BotarguesView Answer on Stackoverflow
Solution 5 - C++Mr. Suryaa JhaView Answer on Stackoverflow
Solution 6 - C++PuppyView Answer on Stackoverflow