I spent a considerable time debugging the following error after compiling the c++ code I am writing:
there are no arguments to <function> that depend on a template parameter, so a declaration of <function> must be available
To make the matters simple and to explain what is happening, lets use the following example. I have a base class which is templated, and a derived class that invokes a function from the base class but the function is not "dependent" ( dependent here means the function depends on the type of the template paramter ). In this case foo is not dependent on the template parameter T. The derived class has a function that invokes foo, this call is also not dependent on the template parameter ( there are no arguments that depend on T ).
template class base{
public:
void foo(int i) {
// do something with i
}
};
template class derived:public base{
int bar() {
foo();
}
};
there are no arguments to <function
To make the matters simple and to explain what is happening, lets use the following example. I have a base class which is templated, and a derived class that invokes a function from the base class but the function is not "dependent" ( dependent here means the function depends on the type of the template paramter ). In this case foo is not dependent on the template parameter T. The derived class has a function that invokes foo, this call is also not dependent on the template parameter ( there are no arguments that depend on T ).
template
public:
void foo(int i) {
// do something with i
}
};
template
int bar() {
foo();
}
};
Again, the call to foo() is not dependent on template arguments (there are no arguments that depend on the type T). This will work only if a global declaration of foo is available, since the one in the base class is not visible until instantiation time, you will get the following compiler error message:
: In member function ‘int derived::bar()’:
error: there are no arguments to ‘foo’ that depend on a template parameter, so a declaration of ‘foo’ must be available
error: (if you use ‘-fpermissive’, G++ will accept your code, but allowing the use of an undeclared name is deprecated)
To solve the problem we have to either use this->foo() or base::foo().
You can also compile with -fpermissive flag which allows the compiler to relax the diagnostics for nonconformant code errors to warnings. Its not a good idea though ( for various reasons that I understand but dont have time to explain for now! :-)
In conclusion, Name lookup is a bit tricky because of the two stage approach by the GCC compiler ( apparently since version 3.4 ). The distinction between lookup of dependent and non-dependent names is called two-stage (or dependent) name lookup. Hope this helps someone who get simliar errors.
2 comments:
I faced this sometime back and can tell you that the this-> based one is more portable. The other base class based one had issues on ARM processors.
@ranjeeth: learnings from ms ??
Post a Comment