2012-06-30 6 views
5

私はこのメンバ関数のテストを持っている:SFINAEは、メンバ関数存在テストの問題

template <typename T> 
struct has_member { 
    template <typename U> static true_type f(decltype(declval<U>().member()) *); 
    template <typename> static false_type f(...); 
    static const bool value = decltype(f<T>(0))::value; 
}; 

指定された名前のメンバ関数が存在する場合それは機能がありませんを取るオーバーロードを有している場合には、trueと評価議論このような関数やSTLコンテナの場合、要素アクセス関数(前面、背面など)を除いて正しく動作しますが、常にfalseと評価されます。

なぜですか?私はmingw g ++ 4.7を持っています。

+0

末尾の戻り値の型に変更するとヘルプになりますか? 'auto f(U * p) - > decltype(p-> member()、true_type());' – Xeo

答えて

6

これは、これらの関数が参照を返し、参照値へのポインタを宣言しているため、参照できません。

クイックフィックスは、次のようになります。

template <typename U> static true_type 
     f(typename remove_reference< decltype(declval<U>().member()) >::type *); 

PS:SFINAEが失敗し、あなたがそれを考える時にエラーを与えるために、コンパイラを強制した場合、エラーのこれらの種類は、解決するために(比較的)簡単にすることができますいけない。

true_typeが唯一のオプションである場合、あなたのコードでは、false_typeをコメントアウトし、コンパイラのエラーを参照してください。無意味な行の間には、次のものがあります。

test.cpp:9:50: error: forming pointer to reference type 
    ‘__gnu_cxx::__alloc_traits<std::allocator<int> >::value_type& {aka int&}’ 
+0

ありがとうございました。 2番目のテンプレート引数として "typename Check = decltype(宣言().front()"を組み込み、fの代わりにcharポインタを代入するようにしました。 –

+0

@ AndrásKovács - このようにさらに優れています。 – rodrigo

関連する問題