任意の数のラムダを取り、すべての呼び出し演算子の中心的な呼び出しポイントとして機能する構造体が必要です。
呼び出し演算子が、構築時に指定されたラムダのいずれとも一致しない引数リストで呼び出された場合、デフォルトの呼び出し演算子を呼び出す必要があります。
私は次のコードがまさにこれを達成すると思った。すべてのラムダの呼び出し演算子は、Poc
を介してusing
クラスに「リフト」されます。
template <typename ...Lambdas>
struct Poc : Lambdas...
{
using Lambdas::operator() ...; // Lift the lambda operators into the class
template <typename ...Ts>
auto operator() (Ts...)
{
std::cout << "general call" << std::endl;
}
};
// Deduction guide
template <typename ...Ts>
Poc(Ts... ts)->Poc<Ts...>;
int main()
{
auto l_int = [](int) {std::cout << "int" << std::endl; };
Poc poc{l_int};
poc(1);//calls the default operator. why?
return 0;
}
構造体にデフォルトの呼び出し演算子がない場合、すべてが期待どおりに機能します(有効な引数リストを使用)。 (上記のコードのように)構造体に追加すると、呼び出す引数に関係なく、デフォルトの演算子が毎回呼び出されます。
私の理解では、lambda-call-operatorsとstructs(デフォルト)call-operatorは同じスコープ内に存在します。したがって、それらはすべてオーバーロード解決のために見られるべきです。 lamdba-operatorは汎用のデフォルト演算子よりも具体的であるため、選択する必要があります。
どうやらそうではありません。何故ですか?
Microsoft Visual C++ 、 Clang 、および [〜#〜] gcc [〜#〜] (すべて最新バージョン)でテストしました。
編集:
見つけたときは簡単です。演算子はconst
で修飾されていませんが、 ラムダの1 は(ラムダをmutable
として定義していない限り)です。したがって、Poc
の非constインスタンスに適しています。
Missing const
を追加するだけです:
auto operator() (Ts...) const