ファンクター呼び出しを転送し、絶対に必要な場合にのみそのファンクターをコピーしたいと思います。これが私の一般的なラッパー関数とファンクターです:
template <typename F>
void wrapper (F func)
{
func ();
}
struct Functor
{
Functor() {}
void operator() () { /* do some work */ }
};
ラッパーを呼び出すことができます
- 右辺値参照: wrapper( Functor() );
- 左辺値参照: ファンクター f; ラッパー(f);
- const 左辺値参照: const Functor f; ラッパー(f);
- const 右辺値参照: const Functor make_functor (); ラッパー (make_functor ());
const 参照が渡された場合にのみラッパーの arg をコピーしたい。だから私はそのようなラッパーの実装に来ます:
using safe_mutual_handler_type =
typename std::conditional<
std::is_reference<F>::value
, typename std::conditional<
std::is_const<typename std::remove_reference<F>::type>::value
, typename std::remove_const<typename std::remove_reference<F>::type>::type
, F&
>::type
, F&
>::type;
template <typename F>
void wrapper (F&& func)
{
safe_mutual_handler_type<F> tmp = func;
tmp ();
}
あまり良くなく、(あまり典型的ではない)const-rvalue-referenceのケースを見逃していますが、基本的には機能します。
しかし、const operator() を持つ Functor もあるかもしれません
struct Functor {
Functor() {}
void operator() () const {}
};
その場合、ラッパーの引数をまったくコピーする必要はありません。
問題は、 Functorに const 括弧演算子がある場合、ラッパーをチェックインするにはどうすればよいかということです。もう 1 つの質問は、ラッパーが、膨大な数の型特性 typedefs の行なしで、よりスマートでコンパクトな方法で実装できるかどうかです。(実際には、コードのサイズではなく、コードの可読性について心配しています)。