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
C++ "Named Parameter Idiom" VS. Boost::Parameter Library
Fast Implementation of Trigonometric Functions for C++
Google Protocol Buffers on iOS
Does Scopeguard Use Really Lead to Better Code
Send Email with Attachment in C++
How to Detect Possible/Potential Stack Overflow Problems in a C/C++ Program
Switch-Case Statement Without Break
Implementing Future::Then() Equivalent for Asynchronous Execution in C++11
Which Header Should I Include for 'Size_T'
Is It Always the Case That Sizeof(T) >= Alignof(T) for All Object Types T
Avoid Warning 'Unreferenced Formal Parameter'
How to Store a Lambda Expression as a Field of a Class in C++11