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

unable to determine the template type even it is passed in

本文关键字:类型 无法确定      更新时间:2023-10-16

我有以下代码:

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是什么,即使它是在函数的模板声明中指定的。

去掉foo.invoke(e)行中显式指定的T将得到could not deduce template parameter 'T'

如何解决这个问题?(我仍然希望保持Caller可以拥有泛型functor和functor的函数可以被模板化的功能)。

您正在使用:

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

Caller内部,尽管TCaller的参数之一。删除

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的语义。如果invoke中的T与用于实例化CallerT不同,那么最好使用不同的名称,例如U

问题是f的类型是F,这是模板参数,f.foo是一个依赖的名称,恰好是一个函数模板。所以你必须以一种非常奇怪的方式使用template:

f.template foo<T>(e);

  • 短解释
  • 长解释

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

希望对你有帮助。