C++14 中对数组的自动右值引用(不带 &&)

Auto Rvalue Reference (without &&) to an Array in C++14

post 的答案 1 How to declare array with auto 工作正常:

template<typename T> using unsized_raw_array = T[];
auto &&z = unsized_raw_array<int>{1, 2, 3};

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

template<typename T> using unsized_raw_array = T[];
auto   z = unsized_raw_array<int>{1, 2, 3};

我预计这是一个错误,因为它是右值 (universal/forwarding/temporary-object) 引用并且缺少双符号 (&&)。这就是 gcc 6.3.0 发生的情况:

然而,clang 3.9.1 成功编译并执行了它,允许在接下来的语句中打印数组的值。我只收到此警告(在某些情况下我什至没有收到警告):

哪个编译器是正确的?

实际上,两个编译器可能都是对的!虽然我不确定具体情况(有人愿意查找吗?),但在很多情况下 C++ 标准只需要提供任何诊断,但并不强制其中的特定情况,因此无论是错误还是警告只能符合标准。

此外,查看您的编译器标志 - 大多数(包括 GCC)编译器允许通过标志将警告转化为错误...

叮当是正确的;参见 [conv.array]:

An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The result is a pointer to the first element of the array.

即使数组是临时数组,因此是纯右值,对其执行数组到指针的转换也是合法的。

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

您可能需要针对 gcc 提交一个新错误,以便他们解决问题。