为何std::result_of无法接受函数类型?代码示例解析
关于std::result_of与函数类型的疑问
以下是测试代码:
int f(int i){ return i; } int main(){ cout << std::boolalpha; using f_1 = decltype(f); using f_2 = decltype((f)); cout << is_same<std::result_of_t<f_1(int)>, int>::value<< endl; // ERROR cout << is_same<std::result_of_t<f_2(int)>, int>::value<< endl; // OK return 0; }
我的分析:decltype(f)会返回函数类型int(int),decltype((f))会返回函数引用类型int(&)(int)。根据std::result_of的文档说明:
F必须是可调用类型、函数引用或可调用类型的引用。使用ArgTypes...调用F必须是合法表达式。
那这是否意味着函数类型不属于可调用类型?
编译器报错信息如下:
1.23.cpp: In function ‘int main()’: 1.23.cpp:35:38: 错误:‘类型名称’被声明为返回函数的函数 35 | cout << is_same<std::result_of_t<f_1(int)>, int>::value<< endl; // ERROR | ^~~ 1.23.cpp:35:46: 错误:模板参数1无效 35 | cout << is_same<std::result_of_t<f_1(int)>, int>::value<< endl; // ERROR | ^ 1.23.cpp:35:52: 错误:模板参数1无效 35 | cout << is_same<std::result_of_t<f_1(int)>, int>::value<< endl; // ERROR | ^
解答
函数类型本身不是可调用类型,而函数引用属于合法的可调用类型范畴。
C++标准定义的可调用类型包括:函数指针、函数引用、成员函数指针、成员数据指针,以及重载了operator()的类类型(仿函数)等。单纯的函数类型int(int)是一种不完整类型,你无法直接声明函数类型的变量——任何类似声明都会被自动调整为函数指针。
回到std::result_of的模板参数逻辑:它的参数形式是F(ArgTypes...),当F是函数类型int(int)时,F(int)等价于int(int)(int),这是一个“返回函数的函数”类型,而C++明确禁止返回函数类型(仅允许返回函数指针或引用),这正是编译器报错的核心原因。
当F是函数引用int(&)(int)时,F(int)等价于调用该引用指向的函数,最终返回值类型为int,完全符合std::result_of的要求,因此可以正常编译。
总结:
decltype(f)确实得到函数类型int(int),但该类型无法直接用于std::result_of的模板参数,会触发非法类型错误。decltype((f))得到函数引用类型,属于合法的可调用类型引用,能正常配合std::result_of使用。
内容的提问来源于stack exchange,提问作者Kevin eyeson
相关产品推荐
相关产品推荐

