2012-11-12 6 views
5

の存在を確認します:テンプレートは、私はクラスが(別の例ではこちらをご覧ください)。このような特別なメンバ関数を持っている場合は、テンプレートを特化してみオーバーロードされたメンバ関数

テンプレートから「はい」を得るためにテストコードを書き直すにはどうすればよいですか?働くバージョンが見つかり

+0

良い質問です。 SFINAEのために静かに検出されない非常に些細な問題。 – iammilind

答えて

1

template <typename C> static one test(decltype(((C*)0)->AnyFunc())*) ; 

を使用すると、そのオブジェクトはconstの機能を持って検証したい場合に、この使用:このバージョンは、引数を持つ関数を検出することができません

template <typename C> static one test(decltype(((const C*)0)->AnyFunc())*) ; 

を:

class B : public std::vector<int> 
{ 
public: 
    //void AnyFunc() const; 
    //void AnyFunc(); 
    int AnyFunc(int); 
}; 
+1

@Klausだから、 'decltype()'の後ろに '*'を追加したのです...投稿した前に動作することを確認しました:http://ideone.com/8Tli7t – PiotrNycz

+0

2番目の答えを読んだ後、私の環境ではどうもありがとう! – Klaus

+0

はい、私はdecltypeの後に*を忘れてしまいました!私のせいで申し訳ありません!私は2番目の答えからstd :: add_pointerの背後を見た後に動作するようにしました。 – Klaus

2

引数なしのオーバーロードされた関数名の使用(13.4p1)は、ル・オーバーロード(13.4p4)。そうしないと、置換に失敗します。

あなたはメンバ関数の存在をテストしている場合、あなたはあなたがそれを呼び出すために計画して引数を知っている必要がありますが:一般的に

template <typename C> static one test(
     typename std::add_pointer<decltype(std::declval<C>().AnyFunc())>::type); 

、あなたは可変長テンプレートとresult_ofと同様のパターンを使用することができます:

template <typename C, typename... Args> static one test(
     typename std::add_pointer<decltype(
      std::declval<C>(std::declval<Args>()...).AnyFunc())>::type); 

add_pointerを使用すると、これは関数の引数の型として許容されない関数の戻り値の型で動作することができます(例えばvoid)。

関連する問題