1. decay
std::decay对类型进行退化处理。
a. T为数组U或数组U引用,则type为U*.
b. T为函数时,则type为std::add_pointer
c. 其它类型则移除cv限定符(const和volatile),则type为std::remove_cv
decay_equiv::value // true decay_equiv ::value // true decay_equiv ::value // true
2. decltype
delctype 可以在编译期内推导表达式所得值的类型。
templatevoid sum(T1 &t1, T2 &t2, decltype(t1 + t2) &s) { s = t1 + t2; } template auto sum(T1 &t1, T2 &t2) ->decltype(t1 + t2)) { return t1 + t2; } int hash(char*); map mm; // 动态指定hash()返回类型,方便后续维护
3. declval
std::declval 返回对象的右值引用,不管对象是否有构造函数,一般配合decltype使用。
struct MyOb { MyObj1(){ cout << "Constuctor" << endl; } int foo() const { return 1; } }; struct MyObj { MyObj(const MyObj&){} int foo() const { return 1; } }; void test() { decltype(MyOb().foo()) n0 = 1; // ok, 构造函数不会调用 decltype(MyObj().foo()) n1 = 1; // 编译错误,MyObj没有默认构造函数 decltype(std::declval().foo()) n2 = 2; // ok, int cout << typeid(n2).name() << endl; // i }
3. 元素分组实例
定义Person结构,如按照人物姓名,年龄,城市各个不同的维度进行分组,可很快写出以下版本:
struct Person { string name; int age; string city; }; templatemultimap GroupBy(const vector & vt, const Fn& keyfn) { multimap map; std::for_each(vt.begin(), vt.end(), [&map, $keyfn](const Person& person) { map.insert({keyfn(person), person}); // keyfn返回值为key }); return map; }
传统方式通过显式指定key类型,可通过c++11语法推导key类型:
方式一:declval
multimap()(declval ())), Person> mp;
方式二. result_of
multimap::type, Person> mp;
方式二使用更加简洁,用result_of改写上述版本:
typedef typename vector::value_type value_type; template multimap ::type, value_type> GroupBy(const vector & vt, const Fn& keyfn) { typedef typename result_of ::type keytype; multimap map; std::for_each(vt.begin(), vt.end(), [&map, &keyfn](const Person& person) { map.insert({keyfn(person), person}); }); return map; } // 调用 multimap mp = GroupBy(v, [](const Person &p) { return p.age; });
cppreference可能实现:
// Minimal C++11 implementation: templatestruct result_of; template struct result_of { using type = decltype(detail::INVOKE(std::declval (), std::declval ()...)); };
参考链接:
https://en.cppreference.com/w/cpp/types/result_of
https://www.cnblogs.com/anzhsoft/p/3602984.html