C++中自动Rvalue引用(没有&&)到数组14

J L*_*J L 3 c++ arrays rvalue-reference auto c++14

回答1帖子 如何声明自动工作正常的数组:

template<typename T> using unsized_raw_array = T[];
auto &&z = unsized_raw_array<int>{1, 2, 3};
Run Code Online (Sandbox Code Playgroud)

尝试相同,但没有双&符号(&&)会导致clang和gcc的不同行为:

template<typename T> using unsized_raw_array = T[];
auto   z = unsized_raw_array<int>{1, 2, 3};
Run Code Online (Sandbox Code Playgroud)

我预计这是一个错误,因为它是一个rvalue(通用/转发/临时对象)引用,并且双&符号缺失(&&).这就是gcc 6.3.0所发生的事情:

  • error: taking address of temporary array

但是,clang 3.9.1会成功编译并执行它,允许在下一个语句中打印数组的值.我只收到这个警告(在某些情况下我甚至没有得到警告):

  • warning: pointer is initialized by a temporary array, which will be destroyed at the end of the full-expression [-Waddress-of-array-temporary]

哪个编译器正确?

Bri*_*ian 6

铿锵是对的; 见[conv.array]:

可以将"数组N T"或"未知范围的数组" 类型的左值或右值T转换为"指向T" 的类型的prvalue .结果是指向数组的第一个元素的指针.

即使数组是临时的,因此也是prvalue,在它上执行数组到指针的转换是合法的.

似乎在解决gcc bug 53220的补丁中引入了将数组prvalues转换为指针的限制.似乎在线程上出现了允许转换是危险的共识,因为从数组初始化指针变量不会延长数组的生命周期.但是,将这些代码视为格式错误并不是正确的解决方案,因为正如后面的线程中所指出的那样,可以以安全的方式使用此转换,例如,如果将数组传递给获取指针的函数(因此将一直存在直到函数返回).

你可能不得不提交一个针对gcc的新bug,以便让他们解决问题.