无法确定模板类型,即使它被传入

时间:2015-05-29 17:35:15

标签: c++ templates c++11

我有以下代码:

template <typename T>
struct Data {
   struct Embed
   { 
      T t;
   };
};

struct Functor {
  template <typename T>
  void foo( typename Data<T>::Embed & e) {}
};
template <typename T, typename F>
struct Caller
{
  F f;
  template <typename T>
  void invoke() {
    typename Data<T>::Embed e;
    f.foo<T>(e); //compiler error pointed this line
   }
 };

然后我将模板专门化为:

 Caller<int, Functor> c;
 c.invoke();

编译器错误是:error: expected primary-expression before '>'行中的f.foo<T>(e);。似乎编译器突然不知道T是什么,即使它在函数的模板声明中指定。

取出T行中明确指定的foo.invoke(e),结果为could not deduce template parameter 'T'

我该如何解决这个问题? (我仍然希望保持Caller可以具有通用仿函数和函子函数的功能可以模板化)。

2 个答案:

答案 0 :(得分:2)

您正在使用:

template <typename T>
void invoke() {
   typename Data<T>::Embed e;
   f.foo<T>(e); //compiler error pointed this line
}
尽管CallerT的参数之一,但在Caller

。删除行

template <typename T>

并使用:

void invoke() {
   typename Data<T>::Embed e;
   // f.foo<T>(e);   //compiler error pointed this line
   f.template foo<T>(e); // Need the template keyword here.
}

然而,正如@Nawaz在评论中指出的那样,它改变了invoke的语义。如果T中的invoke与用于实例化T的{​​{1}}不同,那么最好使用其他名称,例如Caller

答案 1 :(得分:2)

问题是f的类型为F,它是模板参数,f.foo是一个从属名称,恰好是一个函数模板。因此,您必须以非常奇怪的方式使用template

f.template foo<T>(e);

有关进一步说明,请参阅:

此外,我建议您使用U作为功能模板的模板参数invoke ,如果根本需要它是模板,否则您可以制作它是一个正常的函数(即如果调用的T应该与封闭类模板的T相同。)

希望有所帮助。