2017-03-09 4 views
1

クラスにoperator()があるかどうかを確認したいと思います。 私は次のSFINAEを試しました。なぜSFINAEが動作しないのですか?

#include <type_traits> //for std::true_type/false_type 
#include <utility>  //for std::declval 

template <typename T, typename... A> 
class has_call_operator { 
private: 
    template <typename U, typename... P> 
    static auto check(U u, P... p) -> decltype(u(p...), std::true_type()); 
    static auto check(...) -> decltype(std::false_type()); 

public: 
    using type 
     = decltype(check(std::declval<T>(), std::declval<A>()...)); 
    static constexpr bool value = type::value; 
}; 

これは正しいことです。

#include <iostream> 

struct test { 
    void operator()(const int x) {} 
}; 

int main() 
{ 
    std::cout << std::boolalpha << has_call_operator<test, int>::value << std::endl; //true 
    return 0; 
} 

しかし、抽象クラスは正しく機能しませんでした。

#include <iostream> 

struct test { 
    void operator()(const int x) {} 
    virtual void do_something() = 0; 
}; 

int main() 
{ 
    std::cout << std::boolalpha << has_call_operator<test, int>::value << std::endl; //false 
    return 0; 
} 

なぜこのコードは機能しませんか? また、このコードを動作させることができますか?

答えて

2

Uを値で取るので、型の構築も必要です。

これを修正するには、const参照を渡します。

あなたはis_detectedを見て、のようなものがあり:

typename <typename T, typename ...Ts> 
using call_operator_type = decltype(std::declval<T>()(std::declval<Ts>()...)); 

template <typename T, typename ... Args> 
using has_call_operator = is_detected<call_operator_type, T, Args...>; 
関連する問題