Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

error: expected primary-expression before ‘>’: templated function that try to uses a template method of the class for which is templated [duplicate]

Tags:

c++

templates

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?

like image 689
Antonio Avatar asked Dec 16 '22 08:12

Antonio


2 Answers

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.

like image 166
Yakk - Adam Nevraumont Avatar answered Feb 23 '23 00:02

Yakk - Adam Nevraumont


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

like image 28
masoud Avatar answered Feb 22 '23 22:02

masoud