2017-10-07 16 views
1

は、次の関数と同様の挙動を持つ関数を格納することが可能ですforwarding_func。私は後で使うためにそれを格納しなければならないので、std :: functionオブジェクトが必要ですか?関数オブジェクトにこれらのようなラムダを格納することは可能ですか?このケースでは、あなたの引数は左辺値参照であるかどうか分からないようC++ストア機能は

auto f = [](auto&& x){ 
     myfunction(std::forward<decltype(x)>(x)); 
} 
+0

はい、ラムダを使用することは可能です。それらを格納したい場合は、渡されたラムダオブジェクトの型にテンプレート化された 'std :: function'かクラスを使うことができます。 –

+1

std :: functionオブジェクトにこのようなものではなく*を格納することは可能です。 –

+0

あなたの例のラムダは(もしうまくいけば)普遍的なリファレンスではなくrvalueのリファレンス、すなわち、それは引数としてrvaluesを受け入れるだけです。私はあなたが明示的にこれを行う方法を尋ねていることを知っていますが、そこには混乱が残っているようです。ユニバーサル参照とレバル参照の違いについては、Scott Meyerの記事(https://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers)をお読みください。 – Knoep

答えて

2

あなたは、operator()を有するものである関数オブジェクトを、必要とします。この演算子はテンプレートであり、同じ(または類似の)署名をforwarding_funcとして持つ必要があります。さまざまな方法で構築できます。

最も直接的な方法は、C++ 17の汎用ラムダを使用することです。

struct forwarder { 
    template <typename ... Args> 
     void operator()(Args&& ... args) { ... etc } 
}; 

このようなフォワーダを作成する方法はまったく異なります。標準ライブラリにoverload関数を追加する提案があります。 (それはまだ標準の一部ではないとして

auto callable = std::overload (
    (void (*)(int, size_t))(target), 
    (void (*)(std::string, int))(target) 
); 

コンパイラがのstd ::オーバーロードを実装していないが、あなたは簡単にそれを自分で実装したり、ネット上の実装を見つけることができます:あなたはこのようにそれを使用します例えばthis questionを参照)。

0

ユニバーサル参照とstd::forwardは、関数テンプレートで意味をなします。そうであればそのまま転送したい、そうでない場合は転送先のファンクションにmoveとします。それはちょうどstd::fowardのことです。 Hereは、rvalue-referencesと完璧なフォワーディングについてのとても良い紹介です。 テンプレート以外の関数は、引数を値または(左辺値)参照で受け取るかどうかを指定するため、それに応じて移動または移動でき、std::fowardは不要です。

関数テンプレートは実際には関数自体ではないので、ラムダに格納することはできません。ただし、テンプレートoperator()でファンクタを作成することができます。

struct Forwarding_Functor 
{ 
    template<class... T> 
    void operator()(T&&... args) 
    { 
     target(std::forward<T>(args)...); 
    } 
};