即使传入模板类型,也无法确定模板类型
unable to determine the template type even it is passed in
我有以下代码:
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
内部,尽管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
的语义。如果invoke
中的T
与用于实例化Caller
的T
不同,那么最好使用不同的名称,例如U
。
问题是f
的类型是F
,这是模板参数,f.foo
是一个依赖的名称,恰好是一个函数模板。所以你必须以一种非常奇怪的方式使用template
:
f.template foo<T>(e);
- 短解释 长解释
另外,我建议你使用U
作为函数模板invoke
的模板参数,如果它需要是一个模板,否则你可以使它成为一个正常的函数(即,如果调用的T
应该与封闭类模板的T
相同)。
希望对你有帮助。
相关文章:
- c++ 11 带有 decltype 的尾随返回类型无法按预期工作
- 初始值设定项无法确定 C++ 中字符串的大小
- CMake无法确定目标的链接器语言:fileloader
- 无法确定为什么函数调用中从 char* 到 char 的无效转换
- 分析仪无法确定位置
- "无法确定要运行哪个"make"命令.检查构建配置中的"make"步骤
- CMake 错误:无法确定目标的链接语言
- 添加 DIV/0 异常处理。我做错了什么,但无法确定在哪里
- 无法确定未解决的外部错误来自何处
- boost :: Spirit属性分配:struct is_nullary:基本类型无法成为结构或类型
- 无法确定 IDE 在 C++ 中说出未声明标识符的原因
- 无法确定正确的返回类型
- Xalanc转换错误:无法确定文件的基本路径名(,第0,第0列)
- 无法确定打印113383后代码停止的原因
- 将utf8编码的字符串转换为本地8位编码的字符串,并将无法确定的字符替换为空白
- 究竟为什么编译器在运行时之前无法确定变量的真实类型?
- Visual Studio 无法确定全局变量的类型
- 类声明错误:上下文信息不足,无法确定类型
- 即使传入模板类型,也无法确定模板类型
- 上下文信息不足,无法确定类型