decayメタ関数
いつもすぐ忘れるdecay(ディケイ、と読む)メタ関数の機能、その備忘記です。
Boost.TypeTraitsからC++11の
関数テンプレートでは、配列型(T[N])はポインタ(T*)に変換されます。また、関数型(R(Args...))は関数ポインタ(R(*)(Args...))に変換されます。std::decayメタ関数に配列型を渡すとポインタ型が返され、関数型を渡すと関数ポインタ型が返されます。
以下、検証用コード:
#include <iostream> #include <type_traits> template <class T> T array_decay(T x) { static_assert(std::is_same<T, int*>::value, "T must be int*"); return x; } template <class T> T fp_decay(T x) { static_assert(std::is_same<T, int(*)(double)>::value, "T must be int(*)(double)"); return x; } int proc(double) { return 0; } int main() { // 配列型をdecayするとポインタになる { int ar[3] = {1, 2, 3}; using result_type = std::decay<decltype(ar)>::type; static_assert(std::is_same<result_type, int*>::value, ""); int* result = array_decay(ar); } // 関数型をdecayすると関数ポインタになる { // 関数の型は関数ポインタではない static_assert( std::is_same<decltype(proc), int(double)>::value, ""); static_assert(!std::is_same<decltype(proc), int(*)(double)>::value, ""); using result_type = std::decay<int(double)>::type; static_assert(std::is_same<result_type, int(*)(double)>::value, ""); int(*result)(double) = fp_decay(proc); } }