C++11 有效的模板扩展?

C++11 有效的模板扩展?,c++11,template-meta-programming,expansion,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&>

我正在获取一个包含可变类型的结构,提取它们并传递它们 到本机函数调用

//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... );
//ValueArray包含变量类型的向量。
//从ValueArray中提取参数。
模板
内联参数
_processParam(ValueArray和args){
Arg Arg=static_cast(args[0]);
参数擦除(0,真);
返回arg;
}
///执行函数调用。Args是一个可变模板包。
调用(fnPtr,_processParam(args)…);
///电话扩展到:
(*fnPtr)(参数…);

然而,问题是_processParam(args)。。。扩展按类型按相反顺序拉出args。例如,[1,1.4]的ValueArray将以double、then和int的形式拉出。是否有方法正确地以可移植的方式拉出参数?

摆脱
擦除
并添加索引。在进行函数调用时,不要更改其他参数计算中使用的数据,因为顺序是未定义的(这使得编译器可以为了效率或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] )... );
}

函数调用的参数表达式(由非逗号运算符的
分隔)的求值是无序的。对于某些编译器(如g++),顺序是从右到左,即首先计算最右边的参数表达式。您的程序似乎有未定义的行为。大多数编译器是从右向左还是从左向右求值?如果是这样的话,我现在就可以处理这些案子了。否则,有没有办法通过函数调用附加索引?谢谢,我不知道如何获取索引。这看起来像是某种拉链操作。@DanH。答案有所改善。创建一组大小相同的索引,然后在Parralel中展开它们。请注意,C++1y将有
index\u序列
,它完成了上述样板文件的大部分工作。对于不带任何参数的函数,我还需要专门化do\u调用函数,并使用make\u索引代替索引。再次感谢你@丹。真正地惊讶<代码>…在两个空参数包上应该工作吗?也许问题在于它认为它无法从
中推断出
参数…
?它应该是有效的。当尝试包装成员函数、返回void并获取两个参数(而不是这次的一个)时,问题再次出现。它只在这些特定情况下出现,因为我在索引中缺少一个“.”。具有不,是编译器。错误。
do_call<Args...>( make_indexes<sizeof...(Args)>(), arr );