关于C++:错误:在>:之前的预期主表达式:尝试使用模板的类的模板方法的模板化函数

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

本问题已经有最佳答案,请猛点这里访问。

当使用模板和函数(这个问题中不存在)时,我最终得到了以下简化的问题。

以下代码(此处也提供)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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(value);
    }


int main( int argc, const char* argv[] ) {
  const A evaluator;
  evaluator.isGood(20); //Seemingly no problem here
  tryEvaluator(evaluator,20);
  return 0;
  }

生成错误

1
2
3
main.cpp:18:34: error: expected primary-expression before ‘>’ token
         return evaluator.isGood(value);
                                  ^

是否可以执行我正在尝试的操作?我需要添加一些关键字吗?

还有,附带问题,我应该如何更好地重新命名我的问题?


template中,如果变量的类型是template参数的函数,或类型是template参数的函数,则称为依赖类型。

在您的例子中,T类型的evaluator具有依赖于template参数的类型。

当使用依赖类型或该类型的变量时,需要给编译器一些额外的帮助。

编译器希望能够在代码实际填充实例化中的template参数之前部分理解代码。默认情况下,它假定依赖类型中的所有内容都是一个值。

所以evaluator是一个依赖型,evaluator.isGood被假定为一个值,所以evaluator.isGoodevaluator.isGood上使用operator<,在evaluator.isGood上使用一些未知值B(它找不到:错误),那么你就用它的返回值来做>(value)B不是一个值(而是一个类型),因此您的代码有错误。

您必须告诉编译器,isGood不是一个值,而是在依赖上下文中使用时的template

evaluator.template isGood(value)是语法。template告诉编译器"在默认情况下,你会假设一个值正在出现,而不是一个template正在出现"。在template中使用typename也有类似的规则(但typename更早,所以它出现在一个更糟糕的地方),以表明在其他情况下假定为值的实际上是一种类型。

在您的main方法中,evaluator不是依赖类型,因此它不需要帮助。


isGood前加一个template关键字:

1
2
3
4
5
template <class T>
bool tryEvaluator(T& evaluator, int value) {
    return evaluator.template isGood(value);
                     ^^^^^^^^
}

必须明确地告诉编译器,evaluator后面的内容是一个函数模板,因为isGood是一个依赖名称。否则,编译器将被混淆。