Error: expected primary expression before '>: a template function that tries to use the template method of the class for which the template

While playing with a template and functors (not present in this question), I ran into the following simplified problem.

The following code (also available 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); ^ 

Can I do what I'm trying to do? Do I need to add, for example, some keyword?

And, a side question, what is the best way to rename my question?

+4
source share
2 answers

Inside 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 called a dependent type.

In your case evaluator type T evaluator is of type dependent on the template parameters.

When working with a dependent type or variable of this type, you need to provide additional help to the compiler.

The compiler wants to be able to partially understand your code before it actually populates the template parameter there in the instance. By default, it is assumed that everything in the dependent type is a value.

So, evaluator is a dependent type, and evaluator.isGood is considered a value, therefore, evaluator.isGood<B uses operator< on evaluator.isGood and some unknown value B (which it cannot find: error), the return value of which then executes >(value) on. B not a value (but instead a type), so your code is wrong.

You must tell the compiler that isGood not a value, but rather a template when used in a dependent context.

evaluator.template isGood<B>(value) is the syntax. template tells the compiler, "although by default you assume a value will come, template will appear instead." There are similar rules that use typename inside a template (but typename was earlier, so it falls into the crappier spot) to indicate what would otherwise be considered a value, is actually a type.

In your method, main evaluator does not have a dependent type, so it does not need help.

+7
source

Put the 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 the following evaluator is a function template because isGood is a dependent name. Otherwise, the compiler will be confused.

+3
source

Source: https://habr.com/ru/post/1494287/


All Articles