result_of的用法
(一)为什么要使用result_of?
当我们不知道某个可调用对象(普通函数,类成员函数,lambda表达式,function,重载了operator()操作符的函数)的返回值时,result_of可以萃取该可调用的返回值。
(二)使用方式
官方详细解释:https://en.cppreference.com/w/cpp/types/result_of
template< class > class result_of; // not defined,泛化版本
template< class F, class... ArgTypes > class result_of<F(ArgTypes...)>; 特化版本
F为可调用callable对象,ArgTypes是可变模板参数
关于callable(普通函数,类成员函数,lambda表达式,function,重载了operator()操作符的函数)的解释,可以参考:https://zh.cppreference.com/w/cpp/named_req/Callable
(三)例子
#include <type_traits>
int func(int){return 0;} //普通函数
typedef int(*pFunc)(); //函数指针
typedef int(&refFunc)(); //函数引用
struct ClassFunc
{
char operator()(int) { return '0'; }
int operator()(bool) { return 0; }
int test() { return 0; }
float test(int) { return 0; }
static double test(float) { return 0; }
float MyFunc(int) { return 0; }
static int MyTest(int) { return 0; }
};
int main(int argc, char* argv[])
{
/*
decltype(表达式或变量名),萃取表达式或者变量名的对应类型;
函数名是一个变量,不是一个具体类型,所以需要萃取;
*/
//因为func是函数名,是一个常量,不是类型,所以需要decltype萃取类型
std::result_of<decltype(&func)(int)>::type a; //返回类型是 int
//函数名引用
std::result_of<decltype(func)&(int)>::type b; //返回类型是 int
//pFunc通过typedef定义的一个具体类型,所以不需要decltype萃取
std::result_of<pFunc()>::type c; //返回类型是 int
//函数引用的方式
std::result_of<refFunc()>::type d; //返回类型是 int
//operator()(int)
std::result_of<ClassFunc(int)>::type e;//返回类型是 char
//operator()(bool)
std::result_of<ClassFunc(bool)>::type f; //返回类型是 int
int(ClassFunc::*pClassFuncTest1)() = &ClassFunc::test;
/*pClassFuncTest1是个变量所以decltype要萃取,非静态成员函数的调用需要一个对象,所以
result_of的可变参数模板的第一个参数应该是一个类对象*/
std::result_of<decltype(pClassFuncTest1)(ClassFunc)>::type g; //返回类型是 int
float(ClassFunc::*pClassFuncTest2)(int) = &ClassFunc::test;
/*pClassFuncTest2是个变量所以decltype要萃取,非静态成员函数的调用需要一个对象,所以
result_of的可变参数模板的第一个参数应该是一个类对象*/
std::result_of<decltype(pClassFuncTest2)(ClassFunc, int)>::type h; //返回类型是 float
typedef float(ClassFunc::*pFuncTest2Typedef)(int);
/*pFuncTest2Typedef是个typedef声明的类型,本身就是一个类型,所以无需decltype萃取类型,
非静态成员函数的调用需要一个对象,所以result_of的可变参数模板的第一个参数应该是一个类对象*/
std::result_of<pFuncTest2Typedef(ClassFunc, int)>::type hh;
double(*pClassStaticFunc)(float) = &ClassFunc::test;
/*萃取的是静态成员函数的返回类型,所以result_of的模板参数列表不需要类对象,而是当做普通函数来处理*/
std::result_of<decltype(pClassStaticFunc)(float)>::type i; //返回类型是 double
//当没有出现函数重载的时候,可以直接通过取类成员函数地址的方式来萃取
std::result_of<decltype(&ClassFunc::MyFunc)(ClassFunc, int)>::type ii; //返回类型是 float
std::result_of<decltype(&ClassFunc::MyTest)(int)>::type iij; //返回类型是 int
auto lambdaFunc = []()->int {return 0; };
//lambda表达式的函数
std::result_of<decltype(lambdaFunc)()>::type j;
return 0;
}