通过函数传递模板参数时出错
Error on pass template argument through function
我写了一些实用程序来描述 return 类型的函数,如代码所示。为什么将函数传递给 traits 函数后 traits 不能工作?
感谢您的大力帮助。
template <class>
struct FunctionHelper;
template <class R, class... ArgsT>
struct FunctionHelper<R(ArgsT...)> {
typedef R type;
};
template <class R, class... ArgsT>
struct FunctionHelper<R *(ArgsT...)> {
typedef R type;
};
int sum(int a, int b);
int *sum1(int a, int b);
template <class Func>
void traits(Func func) {
typename FunctionHelper<Func>::type value;
}
int main() {
traits(sum); // Here is error. error C2027: use of undefined type
traits<decltype(sum)>(sum); // Here works fine
FunctionHelper<decltype(sum)>::type value; // Here works fine
}
MSVS 14.1 中的错误信息如下所示
[build] E:\source\cpp\function_traits\main.cpp(17,34): error C2027: use of undefined type 'FunctionHelper<Func>' [E:\source\cpp\function_traits\build\func_traits.vcxproj]
[build] with
[build] [
[build] Func=int (__cdecl *)(int,int)
[build] ]
[build] E:\source\cpp\function_traits\main.cpp(17): message : see declaration of 'FunctionHelper<Func>' [E:\source\cpp\function_traits\build\func_traits.vcxproj]
[build] with
[build] [
[build] Func=int (__cdecl *)(int,int)
[build] ]
[build] E:\source\cpp\function_traits\main.cpp(21): message : see reference to function template instantiation 'void traits<int(__cdecl *)(int,int)>(Func)' being compiled [E:\source\cpp\function_traits\build\func_traits.vcxproj]
[build] with
[build] [
[build] Func=int (__cdecl *)(int,int)
[build] ]
[build] E:\source\cpp\function_traits\main.cpp(17,1): error C2065: 'type': undeclared identifier [E:\source\cpp\function_traits\build\func_traits.vcxproj]
[build] E:\source\cpp\function_traits\main.cpp(17,39): error C2146: syntax error: missing ';' before identifier 'value' [E:\source\cpp\function_traits\build\func_traits.vcxproj]
[build] E:\source\cpp\function_traits\main.cpp(17,39): error C2065: 'value': undeclared identifier [E:\source\cpp\function_traits\build\func_traits.vcxproj]
如评论中所述,
template <class R, class... ArgsT>
struct FunctionHelper<R *(ArgsT...)> {
typedef R type;
};
专门 FunctionHelper
用于返回指针的函数,而不是用于
函数指针。
至于
traits(sum); // Here is error. error C2027: use of undefined type
我建议你看看Template argument deduction。
由于你的参数func
不是引用类型,这里:
template <class Func>
void traits(Func func) {
typename FunctionHelper<Func>::type value;
}
以下规则适用:
Before deduction begins, the following adjustments to P and A are made:
If P is not a reference type,
a. [...]
b. otherwise, if A is a function type, A is replaced by the pointer type obtained from function-to-pointer conversion;
template<class T>
void f(T);
// ...
void b(int);
f(b); // P = T, A = void(int), adjusted to void(*)(int): deduced T = void(*)(int)
因此,您的 Func
类型被推断为 int(*)(int,int)
并且编译失败,因为函数指针没有 FunctionHelper
的特化。
您可以通过将 traits
更改为
来获得您期望的行为
template <class Func>
void traits(Func const& func) {
typename FunctionHelper<Func>::type value;
}
我写了一些实用程序来描述 return 类型的函数,如代码所示。为什么将函数传递给 traits 函数后 traits 不能工作? 感谢您的大力帮助。
template <class>
struct FunctionHelper;
template <class R, class... ArgsT>
struct FunctionHelper<R(ArgsT...)> {
typedef R type;
};
template <class R, class... ArgsT>
struct FunctionHelper<R *(ArgsT...)> {
typedef R type;
};
int sum(int a, int b);
int *sum1(int a, int b);
template <class Func>
void traits(Func func) {
typename FunctionHelper<Func>::type value;
}
int main() {
traits(sum); // Here is error. error C2027: use of undefined type
traits<decltype(sum)>(sum); // Here works fine
FunctionHelper<decltype(sum)>::type value; // Here works fine
}
MSVS 14.1 中的错误信息如下所示
[build] E:\source\cpp\function_traits\main.cpp(17,34): error C2027: use of undefined type 'FunctionHelper<Func>' [E:\source\cpp\function_traits\build\func_traits.vcxproj]
[build] with
[build] [
[build] Func=int (__cdecl *)(int,int)
[build] ]
[build] E:\source\cpp\function_traits\main.cpp(17): message : see declaration of 'FunctionHelper<Func>' [E:\source\cpp\function_traits\build\func_traits.vcxproj]
[build] with
[build] [
[build] Func=int (__cdecl *)(int,int)
[build] ]
[build] E:\source\cpp\function_traits\main.cpp(21): message : see reference to function template instantiation 'void traits<int(__cdecl *)(int,int)>(Func)' being compiled [E:\source\cpp\function_traits\build\func_traits.vcxproj]
[build] with
[build] [
[build] Func=int (__cdecl *)(int,int)
[build] ]
[build] E:\source\cpp\function_traits\main.cpp(17,1): error C2065: 'type': undeclared identifier [E:\source\cpp\function_traits\build\func_traits.vcxproj]
[build] E:\source\cpp\function_traits\main.cpp(17,39): error C2146: syntax error: missing ';' before identifier 'value' [E:\source\cpp\function_traits\build\func_traits.vcxproj]
[build] E:\source\cpp\function_traits\main.cpp(17,39): error C2065: 'value': undeclared identifier [E:\source\cpp\function_traits\build\func_traits.vcxproj]
如评论中所述,
template <class R, class... ArgsT>
struct FunctionHelper<R *(ArgsT...)> {
typedef R type;
};
专门 FunctionHelper
用于返回指针的函数,而不是用于
函数指针。
至于
traits(sum); // Here is error. error C2027: use of undefined type
我建议你看看Template argument deduction。
由于你的参数func
不是引用类型,这里:
template <class Func>
void traits(Func func) {
typename FunctionHelper<Func>::type value;
}
以下规则适用:
Before deduction begins, the following adjustments to P and A are made:
If P is not a reference type,
a. [...]
b. otherwise, if A is a function type, A is replaced by the pointer type obtained from function-to-pointer conversion;
template<class T>
void f(T);
// ...
void b(int);
f(b); // P = T, A = void(int), adjusted to void(*)(int): deduced T = void(*)(int)
因此,您的 Func
类型被推断为 int(*)(int,int)
并且编译失败,因为函数指针没有 FunctionHelper
的特化。
您可以通过将 traits
更改为
template <class Func>
void traits(Func const& func) {
typename FunctionHelper<Func>::type value;
}