标准中是否定义了可变参数模板包扩展的顺序? [英] Is the order for variadic template pack expansion defined in the standard?

查看:48
本文介绍了标准中是否定义了可变参数模板包扩展的顺序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为扩展参数包具有以下行为:

I thought that expanding a parameter pack had the following behavior:

// for Args ... p
f(p)...;
// was equivalent to
f(p1); f(p2); ...; f(pn);

但是我刚刚发现gcc(4.6、4.7和4.8)是相反的:

But I just found out that gcc (4.6, 4.7 and 4.8) does it the other way around:

f(pn); ...; f(p2); f(p1);

而c按我的预期去做。

是GCC中的错误,还是按照标准都有效?

Is that a bug in GCC or are they both valid according to the standard?

最小示例

Minimal example

#include <iostream>
#include <string>

template<typename T>
bool print(const unsigned index, const T& value){
  std::cerr << "Parameter " << index << " is " << value << std::endl; 
  return true;
}

template<typename ... Args>
void printAll(Args ... args){
  unsigned i = 0;
  [](...){}(print(i++, args)...);
}

int main(){
  int a = 1; float b = 3.14; std::string c("hello");
  printAll(a, b, c);
}

编译并执行:

$> clang++ -std=c++11 -o test test.cpp
$> ./test
Parameter 0 is 1
Parameter 1 is 3.14
Parameter 2 is hello
$> g++ -std=c++11 -o test test.cpp
$> ./test
Parameter 0 is hello
Parameter 1 is 3.14
Parameter 2 is 1

答案

Answer

Martinho Fernandes很快就在这里发现了错误。问题是参数的评估顺序,而标准(1.9.3)并未定义它:

It didn't take long for Martinho Fernandes to spot the error here. The problem is the order of evaluation of parameters, which is not defined by the standard (1.9.3):


某些其他方面和操作在本国际标准中,抽象机器的名称被描述为未指定的
(例如,对函数自变量的求值顺序)。

Certain other aspects and operations of the abstract machine are described in this International Standard as unspecified (for example, order of evaluation of arguments to a function).


推荐答案


标准中定义了可变模板包扩展的顺序吗?

Is the order for variadic template pack expansion defined in the standard?

是。展开的元素的顺序与包的原始顺序相对应。

Yes. The expanded elements are in an order that corresponds to the original order of the pack.

在测试中,展开 [](... ){}(print(i ++,args)...); 等效于: [](...){}(print(i ++,a),print (i ++,b),print(i ++,c));

In the test, the expansion [](...){}(print(i++, args)...); is equivalent to: [](...){}(print(i++, a), print(i++, b), print(i++, c));.

该测试存在缺陷,因为它测试了函数参数,这是完全不同的事情。如果您尝试执行上面介绍的扩展表格,您将观察到相同的行为。或者,如果代码没有未定义的行为,您可能会这样做,因为变量 i 会多次递增,而递增序列不会被排序。

The test is flawed in that it tests the order of evaluation of function arguments, which is a completely different matter. If you try and execute the expanded form presented above, you will observe the same behaviour. Or you would if the code didn't have undefined behaviour, since the variable i is incremented several times without the increments being sequenced.

这篇关于标准中是否定义了可变参数模板包扩展的顺序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆