2016-12-23 16 views
4

テンプレートに渡された関数の戻り値の型を取得するにはどうすればよいですか?
私はtemplate<typename T>template<typename Result, typename Args...>間の変換する方法がわからない:テンプレートで関数の戻り値の型を取得する

template<typename T> 
void print_name(T f) 
{ 
    static_assert(internal::is_function_pointer<T>::value 
      || std::is_member_function_pointer<T>::value, 
      "T must be function or member function pointer."); 
    typename decltype(f(...)) Result; // ??? 
    typename std::result_of<T>()::type Result; // ??? 
    printf("%s\n", typeid(Result).name()); 
} 

void f_void() {} 
int f_int(int x) { return 0; } 
float f_float(int x, int y) { return 0.f; } 
struct X { int f(int x, float y) { return 0; } }; 

int main() 
{ 
    print_name(f_void); 
    print_name(f_int); 
    print_name(f_float); 
    print_name(&X::f); 
    return 0; 
} 

私は機能print_name内タイプResultを取得できますか?

+0

あなたが到達しようとしているのは、その型を事前に知らなくても変数に結果を得ることであれば、単純な 'auto a = f(x); ' で十分です。 –

+0

@ JanNilsFerner私は彼がコールに使用されるパラメータを持っていないと思う。 – skypjack

答えて

11

可能な解決策は、の戻り値の型とすべてのパラメータを抽出するという関数宣言を使用することです。あなたはそれを定義することすらできません。
それは最小限、実施例以下の:あなたが見ることができるように

#include<typeinfo> 
#include<cstdio> 

template<typename R, typename... A> 
R ret(R(*)(A...)); 

template<typename C, typename R, typename... A> 
R ret(R(C::*)(A...)); 

template<typename T> 
void print_name(T f) 
{ 
    printf("%s\n", typeid(decltype(ret(f))).name()); 
} 

void f_void() {} 
int f_int(int x) { return 0; } 
float f_float(int x, int y) { return 0.f; } 
struct X { int f(int x, float y) { return 0; } }; 

int main() 
{ 
    print_name(f_void); 
    print_name(f_int); 
    print_name(f_float); 
    print_name(&X::f); 
    return 0; 
} 

を、retために提供宣言が提出関数やメンバ関数の同じ戻り値の型を持っています。
decltypeが残ります。

+0

これはSFINAEですか? – Yves

+1

@トーマス私は過負荷と言います。 – skypjack

+0

標準ライブラリには何をしていますか? – einpoklum

関連する問題