假设您要编写一个函数,该函数将一个不透明句柄传递给未知类型的函数(例如,包含具有约定名称的函数的结构的名称),并将参数转发给该函数.
在非变量的情况下,考虑到单参数函数的简单性,有两种方法可以做到这一点:你可以让转发函数接受任意类型的参数,并尝试用它来调用forwardee函数,编译器会抱怨在模板扩展期间,如果结果是不兼容的;或者您可以使用decltype和各种其他机制来确定forwardee函数所期望的参数类型,并明确要求该类型的参数.我不知道这些术语是否有任何可接受的术语,所以我打算称它们为“通过”和“预先”.
直通方法直接推广到具有任意数量参数的函数,但前面的方法却没有.
#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< T>本身可以被清除).有没有办法让它在可变的情况下工作? (你当然可以使用std :: tuple,但这并不令人满意.)
解决方法
没有什么比写下问题让你意识到答案了.
这是一种方式:
template<typename T,typename Args = typename args_of_var<decltype(T::f)>::type> struct up_front_var; template<typename T,typename... Args> struct up_front_var<T,type_list<Args...>> { static void forward(Args... args) { T::f(args...); } };
我不认为有一种方法可以制作顶级功能(你再次遇到原始问题),但这可能不是太糟糕.
仍然很乐意看到其他解决方案.