为 return 类型的专用模板函数使用 auto 时出错
Error using auto for return type of specialised template function
考虑以下代码片段(从更复杂的代码简化而来):
#include <typeinfo>
#include <iostream>
struct A{
template<int S>
void print(){ std::cout << S << std::endl; }
};
struct B{};
template <class T>
A foo(int);
template<>
A foo<B>(int){ return A{}; }
template<class T>
int bar(int){
auto res = foo<T>(0);
std::cout << typeid(res).name() << std::endl;
res.print<5>(); // This line gives an error
return 0;
}
int main() {
bar<B>(0);
return 0;
}
如果我尝试编译它(使用 gcc 或 clang),它会导致以下错误:
main.cpp:21:16: error: expected primary-expression before ')' token
21 | res.print<5>();
我必须:
- 明确声明
res
为 A_int
对象
- 使用
template
关键字 (res.template print<5>();
) 调用方法 print()
为了编译这段代码。
我不太擅长解释标准语言,但据我所知,调用 模板成员函数时需要函数调用中的 template
关键字 在类型 明确依赖于模板参数 的对象上(例如参见 [=24=])。
在这种情况下,我没想到需要关键字 template
,因为 res
应该是 A
类型的对象,它不明确依赖于模板参数(即使它是模板函数调用的结果)。
有人可以帮助我了解我错在哪里,以及什么时候真正需要 template
关键字吗?
提前致谢,如果这是一个重复的问题,我深表歉意,但我找不到类似问题的具体内容。
就编译器所知,在程序的某处它还没有看到存在 foo
的特殊化 T
returns 除了 A
.所以它不能假设 res
总是 A
。因此,res
的类型实际上确实依赖于模板参数T
,那么res.print
毕竟是一个依赖名称。
然后需要 template
关键字让编译器知道 print
之后的尖括号将被解析为构成 template-id 一部分的尖括号,而不是小于运算符。
考虑以下代码片段(从更复杂的代码简化而来):
#include <typeinfo>
#include <iostream>
struct A{
template<int S>
void print(){ std::cout << S << std::endl; }
};
struct B{};
template <class T>
A foo(int);
template<>
A foo<B>(int){ return A{}; }
template<class T>
int bar(int){
auto res = foo<T>(0);
std::cout << typeid(res).name() << std::endl;
res.print<5>(); // This line gives an error
return 0;
}
int main() {
bar<B>(0);
return 0;
}
如果我尝试编译它(使用 gcc 或 clang),它会导致以下错误:
main.cpp:21:16: error: expected primary-expression before ')' token
21 | res.print<5>();
我必须:
- 明确声明
res
为A_int
对象 - 使用
template
关键字 (res.template print<5>();
) 调用方法print()
为了编译这段代码。
我不太擅长解释标准语言,但据我所知,调用 模板成员函数时需要函数调用中的 template
关键字 在类型 明确依赖于模板参数 的对象上(例如参见 [=24=])。
在这种情况下,我没想到需要关键字 template
,因为 res
应该是 A
类型的对象,它不明确依赖于模板参数(即使它是模板函数调用的结果)。
有人可以帮助我了解我错在哪里,以及什么时候真正需要 template
关键字吗?
提前致谢,如果这是一个重复的问题,我深表歉意,但我找不到类似问题的具体内容。
就编译器所知,在程序的某处它还没有看到存在 foo
的特殊化 T
returns 除了 A
.所以它不能假设 res
总是 A
。因此,res
的类型实际上确实依赖于模板参数T
,那么res.print
毕竟是一个依赖名称。
template
关键字让编译器知道 print
之后的尖括号将被解析为构成 template-id 一部分的尖括号,而不是小于运算符。