2017-07-14 4 views
2

以下を考慮して、私が他の関数に渡すタイプがsfのメンバー関数T::mfであるかどうかを確認したいと思います。タイプと名前がありますが、任意の数のオーバーロードがあります。タイプTにメンバー関数のオーバーロードがあるかどうかチェックSFINAE

いくつかの微妙な変化(おもしろそうです)やグーグルで、私は以下のようなコードを手に入れることができますが、問題を表現する方法はわかりません。printは、 。

#include <type_traits> 
#include <utility> 


template <typename T,typename = void> 
struct has_write : std::false_type {}; 

template <typename T> 
struct has_write<T, decltype(std::declval<T>().write())> : std::true_type {}; 


template <typename T, typename R = void , typename ...Args> 
struct has_print : std::false_type {}; 

// cant deduce, specialization never used 
template <typename T, typename ...Args> 
struct has_print<T, decltype(std::declval<T>().print(std::declval<Args>()...))> : std::true_type {}; 


struct Foo { 
    void write(); 
}; 

struct Bar { 
    int print(int, float, int); 
}; 

int main(){ 
    static_assert(has_write<Foo>::value, "Does not have write.."); 
    static_assert(has_print<Bar>::value, "Does not have print.."); 
    return 0; 
} 

上記g++でコンパイルが、第2 assertは失敗し、clangは、もう少し有用であり、それはすべての種類を推測することはできませんのでhas_printのための専門分野が使用されることはありませんと言われます。

+1

AFAIKこれを行う唯一の方法は、何かに暗黙的に変換可能な型の0..Nインスタンスで 'print'を呼び出そうとすることです。リフレクションはこれをもっと容易にするはずです... –

+1

あなたの 'sf'関数は、その関数が知っている特定の引数数で' print'の特定のバージョンを呼び出すので、既知のものを使って特定の 'has_print'を調べることができますタイプ。 – SergeyA

+0

私はこれを考慮しましたが、私はこれを初めて習得しています。タイプがオーバーロードかどうかを調べるクリーンな方法(xyの問題ではない)を知りたがっていました。 – arynaq

答えて

2

sf関数内からオーバーロードを呼び出すので、sf関数を使用して特定のオーバーロードの可用性をチェックする必要があります。

全般の可用性がどの過負荷が重要になることはありませんので、クラス内の任意の過負荷が常に、定義によってXYの問題だろうの可用性をチェックします。与えられた引数のセットで名前を呼び出すことができるかどうかを知る必要があります。これを考えてみましょう:与えられた名前のオーバーロードの可用性を求めることは、概念的には、特定のクラスにがあるかどうかを尋ねるのと同じです。メソッドはまったく同じです。そして明らかにあなたはそれに興味がないでしょうか?

関連する問題