不明な型の関数に不透明なハンドルを渡す関数を記述したいとしましょう(例えば、合意した名前の関数を含む構造体の名前)、引数をその関数に転送します。C++ 11:variadic関数のパラメータ型の計算
単純化のために単一パラメータ関数を考えると、これを行うには2つの方法があります。フォワーディング関数に任意の型の引数を与え、それと転送関数を呼び出そうとすることができます。互換性がないと判明した場合、コンパイラはテンプレートの展開中に文句を言うでしょう。 decltypeやその他のさまざまなメカニズムを使って、転送先関数が期待するパラメータの種類を把握し、その型の引数を明示的に要求することができます。私はこれらの用語を受け入れているかどうかわからないので、私はそれらを "通過"と "前線"と呼ぶつもりです。
パススルー・メソッドは、任意の数のパラメータを持つ関数に直接的に一般化しますが、アップ・フロント・メソッドは一般化しません。
#include <iostream>
template<typename T, typename Arg>
void pass_through_1(Arg arg)
{
T::f(arg);
}
template<typename T> struct arg_of_1;
template<typename Ret, typename Arg>
struct arg_of_1<Ret (Arg)>
{
typedef Arg type;
};
template<typename T>
void up_front_1(typename arg_of_1<decltype(T::f)>::type arg)
{
T::f(arg);
}
template<typename T, typename... Args>
void pass_through_var(Args... args)
{
T::f(args...);
}
template<typename T> struct args_of_var;
template<typename...> struct type_list;
template<typename Ret, typename... Args>
struct args_of_var<Ret (Args...)>
{
// typedef Args... type; // can't do this
typedef type_list<Args...> type;
};
// template<typename T>
// void up_front_var(typename args_of_var<decltype(T::f)>::type... args) // can't do this
// {
// T::f(args...);
// }
struct test
{
static void f(int x) { std::cout << x*9 << std::endl; }
};
int main(int, char**)
{
pass_through_1<test>(7);
up_front_1<test>(8);
pass_through_var<test>(9);
// up_front_var<test>(10);
return 0;
}
問題は、パラメータパックがのみテンプレート引数として、自立をすることを許可されていないということです、そしてあなたが囲んでいるテンプレートでそれらをラップする場合は、場所でそれらを解凍アンラップ-と-する方法はありませんパターンマッチングによってのみ実行されます。
"Up front"には、より良い自己文書化、型推論のサポート(up_front <T>自体を宣言することができます)などの利点があります。それはvariadicの場合に動作させる方法はありますか? (もちろんstd :: tupleを使うこともできますが、これはむしろ満足できません)
"up front"の欠点:オーバーロードされた関数またはデフォルトパラメータを処理できません。 – aschepler
良い点。ユースケースによって異なります。 – glaebhoerl