C 11:计算可变参数函数参数类型

假设您要编写一个函数,该函数将一个不透明句柄传递给未知类型的函数(例如,包含具有约定名称的函数的结构的名称),并将参数转发给该函数.

在非变量的情况下,考虑到单参数函数的简单性,有两种方法可以做到这一点:你可以让转发函数接受任意类型的参数,并尝试用它来调用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...);
    }
};

我不认为有一种方法可以制作顶级功能(你再次遇到原始问题),但这可能不是太糟糕.

仍然很乐意看到其他解决方案.

相关文章

一.C语言中的static关键字 在C语言中,static可以用来修饰局...
浅谈C/C++中的指针和数组(二) 前面已经讨论了指针...
浅谈C/C++中的指针和数组(一)指针是C/C++...
从两个例子分析C语言的声明 在读《C专家编程》一书的第三章时...
C语言文件操作解析(一)在讨论C语言文件操作之前,先了解一下...
C语言文件操作解析(三) 在前面已经讨论了文件打开操作,下面...