There Are No Arguments That Depend on a Template Parameter

There are no arguments that depend on a template parameter

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).

Template inheritance: There are no arguments that depend on a template parameter

When extending a class that depends on a template parameter, this kind of become a dependent name.

The problem is that while performing two phase name lookup, the compiler can't know where he can find the function geta. He cannot know it comes from the parent. Because template specialization is a thing, TestA<int> and TestA<double> could be two completely different clas swith different functions and members.

With the this keyword added, the compiler know that geta must be a member function.

Without that, it could be either a member function or non-member function, or a member function of TestB.

Imagine a template code that will either call a function geta from TestA and geta from TestB depending on some template conditions. Ouch. The compiler want to be sure that the code is consistent for every template instantiations.

Another way of saying to the compiler that the function exist as a member function is to add a using statement:

template <typename T> 
struct TestInh : TestA<T>, TestB<T> {
// some code...

using TestA<T>::geta;

int get_total() {
// works! With the above using statement,
// the compiler knows that 'geta()' is
// a member function of TestA<T>!
return geta();
}
};

error: there are no arguments to 'at' that depend on a template parameter, so a declaration of at must be available

Replace at with vector<T>::at or this->at.

Rules for how functions are looked up in templates are tighter now than when C++ was being originally designed.

Now, methods in dependent bases are only looked up if you this->, otherwise it is assumed to be a global function (or a non-dependent base/class local/etc).

This can help avoid nasty surprises in practice, where what you thought was a method call becomes a global one, or a global call becomes a method call. It also allows earlier checking of template method bodies.

Error: there are no arguments to 'static_assert' that depend on a template parameter

This language feature became available in C++ only with C++11, see:

https://en.cppreference.com/w/cpp/language/static_assert

C++ Error: There are no arguments to 'setw' that depend on a template parameter

The problem is that you aren't including <iomanip>. You need to include that header file because that's what actually declares std::setw.

Notice the compiler error is pretty clear on this: 'setw' was not declared in this scope. It's telling you it doesn't know what setw is. Since setw comes from the <iomanip> header, you need to include that header so the compiler is properly informed and knows what setw is.

g++: error: there are no arguments to 'pow' that depend on a template parameter, so a declaration of 'pow' must be available [-fpermissive]

You need to #include <cmath> and also link in the math library with -lm (on some systems).



Related Topics



Leave a reply



Submit