不明なタイプの関数(たとえば、合意された名前を持つ関数を含む構造体の名前)に不透明なハンドルが渡され、その関数に引数を転送する関数を作成するとします。
非可変個引数の場合、単純化のために単一パラメーター関数を考慮すると、これを行うには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;
}
問題は、パラメータパックがテンプレート引数としてのみ自立することを許可されておらず、それらを囲んでいるテンプレートでラップした場合、パターンマッチングによってのみ、それらを所定の位置でアンラップおよびアンパックする方法がないことです。
「Upfront」には、自己文書化の改善や型推論のサポートの改善など、いくつかの利点があります(up_front <T>自体をdecltypeすることができます)。可変個引数の場合にそれを機能させる方法はありますか?(もちろん、std :: tupleを使用することもできますが、それはかなり満足のいくものではありません。)