C++11 可变参数模板函数调用转发

标签 c++ templates c++11 variadic-templates

我正在尝试弄清楚如何创建一个 C++11 模板函数,它将在两个约定之间转换函数调用:第一个是使用 Variant(注意:变体是一种多态类型,它是子类 IntVariable、DoubleVariant 等),第二个是 C 函数调用。

我们在编译时知道每条信息:参数计数是参数的数量,参数/返回类型取决于 'cfunc' 变量类型。

// We will assume that the two following functions are defined with their correct
// specializations.

template < typename T >
Variant * convertToVariant( T t );

template < typename T >
T convertFromVariant( Variant * variant );

// The following function is incomplete, the question is how to convert the
// variant parameters into a C function call ?

template < typename Return, typename... Arguments >
Variant * wrapCFunction< Return cfunc( Args... ) >(int argc, Variant ** argv) {
    // Here comes the magic call of cfunc, something like :
    if ( argc != mpl::count< Args... >::value )
        throw std::runtime_error( "bad argument count" );
    return cfunc( convertFromVariant< Args... >( argv[ X ] )... );
}

// Example use case :

int foo( int a, int b );

int main(void) {
    int argc = 2;
    Variant * argv[2] = { new IntVariant( 5 ), new IntVariant( 6 ) };

    Variant * res = wrapCFunction< foo >( argc, argv );
    IntVariant * intRes = dynamic_cast< IntVariant >( res );

    return intRes ? intRes->value : -1;
}

最佳答案

使用 indices trick ,这很容易:

template<unsigned...> struct indices{};

template<unsigned N, unsigned... Is>
struct indices_gen : indices_gen<N-1, N-1, Is...>{};

template<unsigned... Is>
struct indices_gen<0, Is...> : indices<Is...>{};

// assuming the parameters were actually like this
template<typename Return, typename... Args, unsigned... Is>
Variant* wrapCFunction(Return (*cfunc)(Args...), int argc, Variant** argv, indices<Is...>) {
    return cfunc(convertFromVariant<Args>(argv[Is])...);
}

template<typename Return, typename... Args>
Variant* wrapCFunction(Return (*cfunc)(Args...), int argc, Variant** argv) {
    if (argc != sizeof...(Args))
        throw std::runtime_error("bad argument count");
    return wrapCFunction(cfunc, argc, argv, indices_gen<sizeof...(Args)>());
}

请注意代码中的一些更改。首先,sizeof...(Args) 产生参数包中的参数数量。其次,我修复了函数的签名以将 cfunc 作为实际参数传递。

关于C++11 可变参数模板函数调用转发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12765182/

相关文章:

c++ - C++中不可避免的是临时对象吗?

c++ - 什么是非推论上下文?

c++ - std::is_copy_constructable 对于 std::vector

c++ - 使用 std::allocator 和 std::move 防止释放的正确方法

c++ - 非成员函数是否可以返回 const 值?

c++ - 关于类模板成员的显式特化的困惑

c++ - 为什么 C++ 编译器不转换模板函数参数以匹配预期的结果类型?

c++ - 从运算符 T &() 中推导出 const

c++ - 警告 : 'auto' type specifier is a C++11 extension [-Wc++11-extensions]

C++ 类成员与成员函数参数相同的标识符