I以下の型特性があります。テンプレート関数に必要な引数の数はどのようにして求めることができますか?
template <class T>
struct Arity : Arity<decltype(&T::operator())> {};
template <class T, class R, class... Args>
struct Arity<R(T::*)(Args...)> {
static constexpr auto value = sizeof...(Args);
};
template <class T, class R, class... Args>
struct Arity<R(T::*)(Args...) const> {
static constexpr auto value = sizeof...(Args);
};
template <class R, class... Args>
struct Arity<R(*)(Args...)> {
static constexpr auto value = sizeof...(Args);
};
機能は、ほとんどのユースケースのためにとる引数の数を見つけるために素晴らしい作品が、それは一つの共通のケースで失敗した:私は信じている
auto l1 = [](int, double){};
Arity<decltype(l1)>::value; // works, 2
auto l2 = [](auto, auto){};
Arity<decltype(l2)>::value; // error: Reference to overloaded function could not be resolved; did you mean to call it?
テンプレート型として渡される型/値に応じて、異なるオーバーロードを選択することができ、あるいは全くオーバーロードを使用できない可能性があるため、テンプレート化された関数/演算子()に対してこの作業を一般的に行うことは不可能です。また、テンプレート引数として渡す有効な型と値を知る方法もありません。しかし、それでも、私はauto
引数を取るラムダの一般的なケースのためにこれを働かせたい。これをより堅牢にし、自動引数を取るラムダをカバーする方法はありますか?
あなたは無資格の候補が得られにくい故障やSFINAEを参照のコンパイルに失敗しますか?関数の引数を数える方法はあると思いますが、現在のバージョンとテンプレート-λ対応のバージョンの間でうまく自動選択するかどうかはわかりません。 –
@BenVoigt 'オーバーロードされた関数への参照を解決できませんでした。それを呼び出すことを意味しましたか? ' – David
それでは、あなたは間違いがあります。これは、 'operator()'のテンプレート引数の有無にかかわらず動作するソリューションを作る上でもう少し苦労します。 –