は、次のコードを考えてみましょう:私はそのテンプレート型引数を指定せずにLambdaSubtask
オブジェクトを宣言することはできません、それはラムダですので、私はそのテンプレート型引数を指定することはできませんので、私はファクトリメソッドを実装しようラムダでテンプレート化されたオブジェクトを返す方法は?
class BaseTask {
// Implementation here
};
class BaseSubtask {
BaseTask *_pTask;
public:
explicit BaseSubtask(BaseTask *pTask) : _pTask(pTask) { }
virtual void Run() = 0;
// The rest of implementation here.
};
template<typename taFunc> class LambdaSubtask {
taFunc _f;
public:
explicit LambdaSubtask(BaseTask *pTask, taFunc&& f)
: BaseSubtask(pTask), _f(std::forward<taFunc>(f))
{ }
LambdaSubtask(const LambdaSubtask&) = delete;
LambdaSubtask& operator=(const LambdaSubtask&) = delete;
LambdaSubtask(LambdaSubtask&&) = delete;
LambdaSubtask& operator=(LambdaSubtask&&) = delete;
virtual void Run() override final { _f(); }
// The rest of implementation here
};
を:
適切でcopy-list-initialization of
LambdaSubtask<lambda_...>
cannot use an explicit constructor
:残念ながら、これはコンパイルエラーを与える
template<typename taFunc> inline LambdaSubtask<taFunc>
MakeLambdaSubtask(BaseTask *pTask, taFunc&& f) {
return { pTask, std::forward<taFunc>(f) };
}
次のようにファクトリメソッドは、私がLambdaSubtask
オブジェクトを取得できます。
BaseTask task; // Initialization of the task is skipped in the example
auto&& lst = MakeLambdaSubtask(&task, [/* Capture here*/]() {
// Implementation here
});
だから、基本的に私は、テンプレートの種類は、ラムダことで、LambdaSubtask
型のローカル変数オブジェクトをしたいです。私は何かを余分にコピーしないようにしたい。確かに私はベンチマークが非常に遅いことを示すようにstd::function
を避けたいと思う。
適切なファクトリメソッドを実装する方法、またはローカル変数オブジェクトLambdaSubtask
を別の方法で取得する方法を知っていますか?
コンパイラはMSVC++ 2017でツールセットv141を使用しているため、C++ 11/14/17は部分的にサポートされています。
'{のstd前方:: pTask(F)} LambdaSubtask を返す;'、あなたはおそらくLambdaSubtask <はstd :: decay_t > ' –
Justin
@Justinは、私の知る限り、これはコピー/移動コンストラクタを伴うだろう'たいが、 'LambdaSubtask'。'LambdaSubtask'自体の移動は効率化することができますが、メンバー変数として持つラムダの効率がどれだけ効率的かはわかりません。 –
関数型 'F'を持っている場合、rvalueまたはlvalueを使って' MakeLambdaSubtask'を呼び出したかどうかによって 'taFunc'は' F'または何らかの 'F&'になります。もしそれが 'F&'だったならば、あなたの 'LambdaSubtask'は動かない、割り当て不可能な、などです。それはあなたが望むものかもしれませんが、予期しないことです。私は予期しない動作を避ける傾向がありますが、それはあなた次第です – Justin