間接参照演算子の標準関数オブジェクトがある場合(withstd::plus<T>
を追加する場合と同様)、ネストされたバインド式を含めることができますが、そうではありません。さらに、通常の置換を行うため、呼び出し演算子が必要になります。ネストされたバインド式の評価中の配置は、最初の引数には適用されません!あなたのソリューションは追加を導入するので、私はそうでないいくつかの代替案を提案しています。T
T
std::function
独自の呼び出し演算子と間接参照演算子を記述します。
struct call {
template<typename Callable, typename... Args>
auto operator()(Callable&& callable, Args&&... args) const
// don't use std::result_of
-> decltype( std::declval<Callable>()(std::declval<Args>()...) )
{ return std::forward<Callable>(callable)(std::forward<Args>(args)...); }
};
struct dereference {
template<typename T>
auto operator()(T&& t) const
-> decltype( *std::declval<T>() )
{ return *std::forward<T>(t); }
};
template<typename IndirectCallable, typename... Args>
auto indirect_bind(IndirectCallable&& f, Args&&... args)
-> decltype( std::bind(call {}
, std::bind(dereference {}, std::declval<IndirectCallable>())
, std::declval<Args>()... ) )
{ return std::bind(call {}
, std::bind(dereference {}, std::forward<IndirectCallable>(f))
, std::forward<Args>()... ); }
その後、行うことができますauto g = indirect_bind(f, 0.0);
。これは、プレースホルダーが適切に処理される方法も示す概念実証です。
ファンクターは便利なレンガが好きcall
で便利なので、上記の解決策について言及します。私は個人的にツールの中にそれらを持っています。dereference
ただし、私の好ましい解決策は、間接参照を実行して一度に呼び出すポリモーフィックファンクターを作成することです。
template<typename Indirect>
struct indirect_callable_type {
// Encapsulation left as an exercise
Indirect f;
template<typename... Args>
auto operator()(Args&&... args)
// don't use std::result_of
-> decltype( std::declval<Indirect&>()(std::declval<Args>()...) )
{ return f(std::forward<Args>(args)...); }
template<typename... Args>
auto operator()(Args&&... args) const
// don't use std::result_of
-> decltype( std::declval<Indirect const&>()(std::declval<Args>()...) )
{ return f(std::forward<Args>(args)...); }
// Lvalue and rvalue *this version also left as an exercise
};
template<typename T>
indirect_callable_type<typename std::decay<T>::type>
make_indirect_callable(T&& t)
{ return { std::forward<T>(t) }; }
実際、これをとして使用できますauto g = std::bind(make_indirect_callable(f), 0.0);
。
あなたのソリューションとは異なり、それらはいくつかのタイプをアウトオブラインで書く必要があることを言及する必要があります。これは、ラムダ式に固有の制限があるため、不幸な状況です。あなたが現在持っているものに固執したいのであれば、ラムダ内にstd::forward<Args>(args)...
パラメータを置くことを少しお勧めします。これは、移動専用タイプを扱う場合に役立つことがあります。