2017-10-30 12 views
2

私は少しis_callableの特性を実装して、myselを改善しようとしています。しかし、私は少し問題を実行しています。問題は、引数(またはラムダ)を持つ関数を使用しようとしているときに発生します。 私は引数の型を渡す方法を見つけ出すことはなかった、またはそれらを自動的に推定する方法を...ここに私のコードとの結果である:SFINAE、呼び出し可能な形質です

#include <iostream> 
#include <type_traits> 
#include <cstdlib> 



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

template<typename R, typename ...Args> 
struct is_callable_impl<R(Args...), std::void_t <R(Args...)>> : std::true_type {}; 

template<typename Fn> 
struct is_callable_impl < Fn, std::void_t<decltype(std::declval<Fn>()())>> : std::true_type{}; 

struct fonctor { 
    void operator()() {} 
}; 

struct fonctor2 { 
    void operator()(double) {} 
}; 

int fonct(); 
int fonct2(double); 


int main() { 
    auto l = [](float) {return false; }; 
    auto l2 = [&l] {return true; }; 
    std::cout << "expr" << std::endl; 
    std::cout << is_callable_impl<double()>::value << std::endl; //write 1 
    std::cout << is_callable_impl<int(int)>::value << std::endl; // write 1 
    std::cout << is_callable_impl<void(double)>::value << std::endl;// write 1 
    std::cout << is_callable_impl<void(double, int)>::value << std::endl; // write 1 

    std::cout << "lambda" << std::endl; 
    std::cout << is_callable_impl<decltype(l)>::value << std::endl;// write 0 
    std::cout << is_callable_impl<decltype(l2)>::value << std::endl;// write 1 

    std::cout << "function" << std::endl; 
    std::cout << is_callable_impl<decltype(fonct)>::value << std::endl;// write 1 
    std::cout << is_callable_impl<decltype(fonct2)>::value << std::endl;// write 1 

    std::cout << "functors" << std::endl; 
    std::cout << is_callable_impl<fonctor>::value << std::endl; // write 1 
    std::cout << is_callable_impl<fonctor2>::value << std::endl; // write 0 

    std::cout << "uncalled type" << std::endl; 
    std::cout << is_callable_impl<int>::value << std::endl;// write 0 

    system("pause"); 
    return 0; 
} 
+0

はいインスピレーションのためのC++ 11月14日 –

+2

提案で実現することは容易である:(24分の周囲を参照)https://www.youtube.com/watch?v=ovxNM865WaU&index=50&list=PLHTh1InhhwT6bwIpRk0ZbCA0N2p1taxd6を –

答えて

0

オーケー、私は別のアイデアをテストしました。 std :: is_functionを使用すると、オブジェクトが関数か式かを検出できます。 その後、operator = existかどうかを確認するだけです。しかし、functorがoperator()関数をオーバーロードしていると、私の実装はうまくいきません。

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

template<typename F> 
struct is_callable_impl < F, std::enable_if_t < std::is_function<F>{}>> // Expression and Functions 
    : std::true_type {}; 

// Lambda and functor 
template<typename F> 
struct is_callable_impl < F, std::void_t<std::enable_if_t < !std::is_function<F>{} >, decltype(&F::operator())>> : std::true_type{}; 
関連する問題