有效的模板扩展?

时间:2014-01-25 19:31:46

标签: c++11 template-meta-programming expansion

我正在采用包含可变类型的结构,提取它们并传递它们 到本地函数调用。

//ValueArray contains a vector of a variant type.

// Pulls out an argument from a ValueArray.
template<typename Arg>
inline Arg
_processParam( ValueArray& args ) {
    Arg arg = static_cast<Arg&>( args[ 0 ] );
    args.erase( 0, true );
    return arg;
}


/// Do the Function call. Args is a variadic template pack.
call( fnPtr, _processParam<Args>( args )... );

/// The call expands to:
(*fnPtr)( params... );

然而问题是_processParam(args)...扩展以相反的顺序按类型拉出args。例如,[1,1.4]的ValueArray将被拉出为double,然后是int。有没有办法正确地以可移植的方式提取参数?

1 个答案:

答案 0 :(得分:1)

摆脱erase并添加索引。在进行函数调用时,不要改变其他参数计算中使用的数据,因为顺序是未定义的(这使得编译器可以为了效率或miin的阶段对它们进行重新排序)。

您需要添加一个间接级别才能轻松完成此操作:

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

template<unsigned num, unsigned... Is>struct make_indexes:
  make_indexes<num-1, num-1, Is...>{};
template<unsigned...Is>struct make_indexes<0,Is...>:indexes<Is...>{};

template<typename... Args, unsigned...Is>
void do_call(indexes<Is...>, ValArray& arr){
  call( fnPtr, ProcessParam<Args>( arr[Is] )... );
}

其中ProcessParam现在采用的元素不是数组,并使用它:

do_call<Args...>( make_indexes<sizeof...(Args)>(), arr );