c++ - 大括号初始化与括号错误

标签 c++ c++11 gcc list-initialization

我为此提交了一个 GCC 错误,但我宁愿仔细检查一下。

考虑以下程序:

#include <utility>
template<typename T, typename A>
void F(A&& a) { T(std::forward<A>(a)); } // Note: () syntax.
int main() { int i; F<int&>(i); }

和:

#include <utility>
template<typename T, typename A>
void F(A&& a) { T{std::forward<A>(a)}; } // Note: {} syntax.
int main() { int i; F<int&>(i); }

最新的 Clang 和 MSVC 编译器接受这两个程序。 GCC 5 及更高版本接受第一个程序但拒绝第二个程序,声称 将类型为“int”的右值表达式无效转换为类型为“int&”

这是 GCC 错误吗?或者这确实是上述上下文中 T{}T() 之间的区别(因此是 Clang 和 MSVC 中的错误)?

编辑:

问题可以缩小为以下更简单的摘录:

int i; (int&){i};

int i; (int&)(i);

最佳答案

有两个不同的问题:

  • 不清楚标准是什么T{x}应该做引用类型 T .目前[expr.type.conv]/1说它创建了一个类型为 T 的纯右值,这对引用类型来说是无稽之谈。这是 core issue 1521 .
  • 理智的事情可能是T{x}供引用类型 T大致做T __tmp{x};然后产生相当于 static_cast<T>(__tmp) (因此右值引用的 xvalue T 和左值引用的 lvalue T )。然而,发布的 C++11 搞砸了引用列表初始化的规范,使其总是创建一个临时的。结果是 int i; int &r{i};编译失败,因为它会尝试绑定(bind) ri 的临时拷贝,这显然是无稽之谈。这是由 core issue 1288 修复的, 其分辨率 GCC 应该实现,但从错误消息中看似乎没有完全修复。

关于c++ - 大括号初始化与括号错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39840117/

相关文章:

c - HDF-EOS 配置失败, "C compiler cannot create executables"

c++ - 使用 phong 照明的纹理映射

c++ - 数组和指针

c++ - C++11 基于范围的 for 循环条件是否在每个循环中都得到评估?

c++ - 我正在尝试使用 stoi(),但编译器正在尝试给我替换并且不会编译

linux - Linux 上的 _emit 相当于什么?

C++ 错误 : Expected an identifier

c++ - C++套接字-客户端出现段错误(Linux)

c++ - 使用带有 libcxx 的套接字函数 bind() 编译代码失败

gcc - 将参数或变量指定为 __attribute__ ((unused)) 是否允许编译器执行任何其他优化?