2017-06-23 8 views
1

私の目的は、関数と引数のリストをとり、その関数の署名を返す関数を作ることです。それは最初は簡単に聞こえるが、主な使い方は、特定の引数に対して選択された関数のオーバーロードを認識するのを助けることであり、テンプレートは私にとっては役に立たない。私はすでにスタック上のコードを見つけました。これは、変数の型を出力することができますが、オーバーロードにマッチするポインタを取得することは別の話です。次のように 私の最初の試みでした:引数の型に基づいて一致するオーバーロードを取得する

template<typename F, typename... Args> 
auto sig(F f, Args... args) -> decltype(f(std::forward<Args>(args)...), void()) { 
    std::cout << get_name<decltype(f)>() << '\n'; 
} 

そして、それは動作します...限り、関数が何のオーバーロードがありませんよう。たとえば、次のようにこれらの機能を持つ

void foo(bool) {} 
void fun(double&&) {} 
void fun(int&&) {} 

私はそれがいくつかのマクロが必要です

template<typename... A> 
using sign = decltype(fun(std::declval<A>()...))(*)(A...); 

に付属のいくつかは、グーグルの後、私は

sig(foo, true); 

なく

sig(fun, 5.5); 

を行うことができます任意の機能(楽しいですha今のところrdcoded)、それは大丈夫です。問題は、基本的に一致するオーバーロードがあるかどうかをチェックするだけで、返されるシグネチャは戻り値の型について正しいことです。

この時点で、私は次の試してみたいものをかなり失っています。私のgoogle-fuは失敗しています。私はそれにいくつかの助けに感謝したいと思います。今

答えて

1
#define RETURNS(...) \ 
    noexcept(noexcept(__VA_ARGS__)) \ 
    -> decltype(__VA_ARGS__) \ 
    { return __VA_ARGS__; } 

#define OVERLOADS_OF(...) \ 
    [](auto&&...args) \ 
    RETURNS(__VA_ARGS__(decltype(args)(args)...) 

Here is link to wandbox if anyone wants to play with what is already done.

sig(OVERLOADS_OF(fun), 5.5); 

は何をしたいん。

#define OVERLOADS_OF(...) \ 
    [](auto&&...args) => __VA_ARGS__(decltype(args)(args)...) 

または

sig([](auto&&x)=>fun(decltype(x)(x)), 5.5); 

あるいは簡潔変種にこれを簡素化するpost-C++17 proposalがあります。

+0

プロポーザルへのリンクを投稿できますか?ちょっと興味があるんだけど。ありがとうございました。上記の@skypにリンクされている – skypjack

+1

。 – Yakk

+0

ありがとうございました!あなたが私に与えてくれたことは、関数のオーバーロードのためのプロキシを作成し、その上でsigを呼び出すことが可能になりました。それはクールです。しかし、gccは 'main():: 'を出力するので、オーバーロードが選択された情報は残っています。それが受け入れると宣言した議論の - それが私が後にしているものです。 – Stoic

関連する問題