2017-03-13 12 views
4

次のコードは、コンパイル時に一致するstd :: functionコンストラクタを呼び出さないためコンパイルされません。std :: functionの型減算

しかし、上記の例で期待されているのと同じ(または同様の)機能を提供することは可能ですか?呼び出し可能な関数を受け入れるエレガントな方法はありますか?

invoke([](int x) -> int { return x/2; }, 100); //Should return int == 50 

bool (*func_ptr)(double) = &someFunction; 
invoke(func_ptr, 3.141); //Should return bool 

+1

ルックでライブサンプル(のhttp://en.cppreference .com/w/cpp /ユーティリティ/機能/呼び出し) – Constructor

答えて

5

は、テンプレートパラメータとして呼び出し可能なタイプを取る:

template <typename Func, typename Arg> 
auto invoke(Func&& f, Arg&& x) -> decltype(f(std::forward<Arg>(x))) { 
    return f(std::forward<Arg>(x)); 
} 

私はさらに一歩進み、引数のパラメータパックを取るあなたは、単一のarg呼び出し可能オブジェクトに限定されないように:

template <typename Func, typename... Args> 
auto invoke(Func&& f, Args&&... x) -> decltype(f(std::forward<Args>(x)...)) { 
    return f(std::forward<Args>(x)...); 
} 
6
#include <functional> 
#include <cassert> 

template <typename F, typename X> 
auto invoke(F&& f, X x) -> decltype(std::forward<F>(f)(x)) { 
    return std::forward<F>(f)(x); 
} 

int func(char x) { 
    return 2 * (x - '0'); 
} 

bool someFunction(double) {return false;} 

int main() { 
    auto val = invoke(func, '2'); 
    assert(val == 4); 
    auto val2 = invoke([](int x) -> int { return x/2; }, 100); 
    assert(val2 == 50); 
    bool (*func_ptr)(double) = &someFunction; 
    bool b = invoke(func_ptr, 3.141); 
    return 0; 
} 

[ `のstd :: invoke`]でhttp://melpon.org/wandbox/permlink/zpkZI3sn1a76SKM8