我有以下代码:
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可以具有通用仿函数和函子函数的功能可以模板化)。
答案 0 :(得分:2)
您正在使用:
template <typename T>
void invoke() {
typename Data<T>::Embed e;
f.foo<T>(e); //compiler error pointed this line
}
尽管Caller
是T
的参数之一,但在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
相同。)
希望有所帮助。