While playing with template and functors (not present in this question) I ended up with the following simplified problem.
The following code (available also here)
class A {
public:
template <class T>
bool isGood(int in) const {
const T f;
return in < f.value();
}
};
class B {
public:
int value() const {return 10;}
};
template <class T>
bool tryEvaluator(T& evaluator, int value) {
return evaluator.isGood<B>(value);
}
int main( int argc, const char* argv[] ) {
const A evaluator;
evaluator.isGood<B>(20); //Seemingly no problem here
tryEvaluator(evaluator,20);
return 0;
}
generates an error
main.cpp:18:34: error: expected primary-expression before ‘>’ token
return evaluator.isGood<B>(value);
^
Is it it possible to perform what I am trying to do? Do I need to add for example some keyword?
And, side question, how should I better rename my question?
Within a template
, if you have a variable whose type is a function of your template
parameters, or a type whose type is a function of your template
parameters, this is known as a dependent type.
In your case, evaluator
of type T
has a type dependent on the template
parameters.
When working with a dependent type, or a variable of that type, you need to give the compiler some extra help.
The compiler wants to be able to partially understand your code before it actually stuffs the template
parameter in there in the instantiation. By default, it assumes that everything in a dependent type is a value.
So evaluator
is a dependent type, and evaluator.isGood
is assumed to be a value, so evaluator.isGood<B
is using operator<
on evaluator.isGood
and some unknown value B
(which it cannot find: error), whose return value you then do >(value)
on. B
is not a value (but is instead a type), so your code is in error.
You have to tell the compiler that isGood
is not a value, but rather a template
when it is used in a dependent context.
evaluator.template isGood<B>(value)
is the syntax. The template
tells the compiler "while by default you'd assume a value is coming, instead a template
is coming". There are similar rules involving using typename
within a template
(but typename
was earlier, so it goes in a crappier spot) to indicate what would otherwise be assumed to be a value is actually a type.
In your main
method, the evaluator
is not of a dependent type, so it doesn't need the help.
Put a template
keyword before isGood
:
template <class T>
bool tryEvaluator(T& evaluator, int value) {
return evaluator.template isGood<B>(value);
^^^^^^^^
}
You must explicitly tell the compiler that what follows evaluator
is a function template, because isGood
is a dependent name. Otherwise, the compiler will be confused..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With