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

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.

于 2013-07-30T13:14:33.510 に答える
3

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

于 2013-07-30T13:14:29.043 に答える