std::result_of用法
template <class Fn, class... ArgTypes>
头文件:
<type_traits>
用于在编译的时候推导出一个可调用对象(函数,std::funciton或者重载了operator()操作的对象等)的返回值类型.主要用于模板编写中.
模板参数:
Fn
可调用对象
ArgTypes...
参数列表. 注意是类型(int , string等)
成员:
type
可调用对象的返回类型.(主要用该成员来获得结果)
一个简单的实例:
#include <iostream>
#include <type_traits>
int fn(int) {return int();} // function
typedef int(&fn_ref)(int); // function reference
typedef int(*fn_ptr)(int); // function pointer
struct fn_class { int operator()(int i){return i;} }; // function-like class
int main() {
typedef std::result_of<decltype(fn)&(int)>::type A; // int
typedef std::result_of<fn_ref(int)>::type B; // int
typedef std::result_of<fn_ptr(int)>::type C; // int
typedef std::result_of<fn_class(int)>::type D; // int
std::cout << std::boolalpha;
std::cout << "typedefs of int:" << std::endl;
std::cout << "A: " << std::is_same<int,A>::value << std::endl;
std::cout << "B: " << std::is_same<int,B>::value << std::endl;
std::cout << "C: " << std::is_same<int,C>::value << std::endl;
std::cout << "D: " << std::is_same<int,D>::value << std::endl;
return 0;
}
输出结果:
typedefs of int: A: true B: true C: true D: true
一个模板中应用的实例:
有一个vector<Person>,Person就是一个简单的结构体,包含name,age,city三个字段,想要编写一个Group_by函数,实现对这个vector<Person>按Person的某个字段分组.
因为字段未定,编写一个模板比较好.
思路是向Group_by传一个函数,让用户决定这个字段.分组比较简单,数据插入一个multimap<T,Person>返回即可,但是定义multimap中的T类型由用户传入的函数决定.于是这时候就可以用result_of来确定函数的返回值,即T的类型.
#include<iostream>
#include<map>
#include<string>
#include<vector>
#include<algorithm>
#include <utility>
using namespace std;
struct Person
{
string name;
int age;
string city;
};
vector<Person> vt ={
{"aa",20,"shanghai"},
{"bb",25,"beijing"},
{"cc",20,"nanjing"},
{"dd",25,"nanjing"}
};
//Group_by函数
template<typename Fn>
multimap<typename result_of<Fn(Person)>::type, Person> GroupBy(const vector<Person>& vt,const Fn& keySelect)
{
typedef typename result_of<Fn(Person)>::type key_type;
multimap<key_type,Person> map;
for_each(vt.begin(),vt.end(),
[&](const Person& p){
map.insert(make_pair(keySelect(p),p));
});
return map;
}
int main()
{
//按年龄分组
auto res = GroupBy(vt, [](const Person& p){ return p.age; });
//按城市分组
auto res1 = GroupBy(vt, [](const Person& p) { return p.city; });
//打印结果
cout << "----------group by age:---------------" << endl;
for_each(res.begin(),res.end(),[](decltype(res)::value_type & p){
cout << p.second.name <<" " << p.second.city << " " << p.second.age << endl;
});
cout << "----------group by city:---------------"<< endl;
for_each(res1.begin(),res1.end(),[](decltype(res1)::value_type & p){
cout << p.second.name <<" " << p.second.city << " " << p.second.age << endl;
});
return 0;
}
运行结果:
写在最后:
本例还可以不使用std::result_of的方法,通过尾置返回类型推导实现