2017-12-13 7 views
1

SFINAEの仕組みを理解しようとしています。SFINAEを使用してメンバー機能をチェックして電話する

私のニーズ:

私はactivateと呼ばれるメンバ関数を提供したりしないことがありタイプのセットを持っています。指定された型に対してactivateが存在する場合は、引数を受け入れることができます。私は、型のactivateが存在する場合はそれを転送する関数を書いています。それ以外の場合は単にreturn trueです。

私が試した:

#include <iostream> 
#include <utility> 
#include <functional> 

struct A 
{ 
    bool activate() 
    { 
     std::clog << "A::activate() called" << std::endl; 
     return true; 
    } 

    bool activate(const char*) 
    { 
     std::clog << "A::activate(const char*) called" << std::endl; 
     return true; 
    } 
}; 

struct B 
{ 
    // NOTHING 
}; 

template<class S, class... ARGS> 
auto activate(S& s, ARGS&&... p_args) -> typename std::invoke_result<decltype(&S::activate)(S, ARGS...)>::type 
{ 
    return s.activate(std::forward<ARGS>(p_args)...); 
} 

bool activate(...) 
{ 
    return true; 
} 


int main(int argc, char* argv[]) 
{ 
    A a; 
    B b; 

    activate(a); 
    activate(a, "Hello"); 
    activate(b); 

    return 0; 
} 

をしかし、何も今までに印刷されません。どうして?

答えて

3

あなたの問題はここにある:

template<class S, class... ARGS> 
auto activate(S& s, ARGS&&... p_args) 
    -> typename std::invoke_result<decltype(&S::activate)(S, ARGS...)>::type 
//           ^^^^^^^^^^^^ 

それはAのためであるようactivateは、オーバーロードされたメンバ関数であるならば、あなたはdecltypeを経由して、そのアドレスを取ることができません。第二に、それはinvoke_resultの不正な使用です - それはresult_ofの構文を使用しませんF(Args...)、あなたはちょうどinvoke_result<F, Args...>を行います。それはより簡単です。

template<class S, class... ARGS> 
auto activate(S& s, ARGS&&... p_args) 
    -> decltype(s.activate(std::forward<ARGS>(p_args)...)) 

このオーバーロードされた名前の質問を側は、段階的に説明し、どのようにinvoke_resultを使用する方法:あなたが欲しい

はただ直接それを自分で呼び出すことがあります。

+0

私はまだ 'invoke_result'が' result_of'と同じ構文をしていないのを見たことがありません。そして、ええ、アドレスのために、それは理にかなっています。ありがとうございました。 –

関連する問題