4

在使用模板和仿函数(此问题中不存在)时,我最终遇到了以下简化问题。

以下代码(也可在此处获得)

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;
  }

产生错误

main.cpp:18:34: error: expected primary-expression before ‘&gt;’ token
         return evaluator.isGood<B>(value);
                                  ^

是否可以执行我正在尝试做的事情?我是否需要添加一些关键字?

而且,附带问题,我应该如何更好地重命名我的问题?

4

2 回答 2

9

在 atemplate中,如果您有一个类型是参数的函数的变量template,或者类型是template参数的函数的类型,则这称为依赖类型。

在您的情况下,evaluator类型T的类型取决于template参数。

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

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

evaluator依赖类型也是如此,并且evaluator.isGood被假定为一个值,因此evaluator.isGood<B使用operator<onevaluator.isGood和一些未知值B(它无法找到:错误),然后您>(value)对其返回值进行处理。 B不是一个值(而是一个类型),所以你的代码是错误的。

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

evaluator.template isGood<B>(value)是语法。告诉编译器“template默认情况下你会假设一个值即将到来,而不是 atemplate即将到来”。有类似的规则涉及typename在 a 内使用template(但typename更早,所以它在一个更糟糕的地方)来指示否则会被认为是一个值的东西实际上是一个类型。

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

于 2013-07-30T13:14:33.510 回答
3

在前面加上一个template关键字isGood

template <class T>
bool tryEvaluator(T& evaluator, int value) {
    return evaluator.template isGood<B>(value);
                     ^^^^^^^^
}

你必须明确告诉编译器后面evaluator是一个函数模板,因为isGood它是一个依赖名称。否则,编译器会混淆..

于 2013-07-30T13:14:29.043 回答