大括号初始化vs.括号错误
Brace-initialization vs. Parenthesis Bug
我正在为此提交一个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及以上版本接受第一个程序,但拒绝第二个程序,声称invalid cast of an rvalue expression of type 'int' to type 'int&'
。
这是一个GCC bug吗?或者这确实是上述上下文中T{}
和T()
之间的差异(因此是Clang和MSVC中的错误)?
这个问题可以归结为以下几个更简单的摘录:
int i; (int&){i};
和
int i; (int&)(i);
有两个独立的问题:
- 标准没有明确
T{x}
对于参考类型T
应该做什么。目前[expr.type。conv]/1表示它创建了一个类型为T
的右值,这对于引用类型来说是无意义的。这是核心问题1521 同样的事情可能是让
T{x}
对引用类型T
执行大致的T __tmp{x};
,然后产生相当于static_cast<T>(__tmp)
的值(因此右值引用T
的xvalue和左值引用T
的lvalue)。然而,发布的c++ 11搞砸了引用的列表初始化规范,使得它总是创建一个临时对象。结果是int i; int &r{i};
编译失败,因为它试图将r
绑定到i
的临时副本,这显然是没有意义的。这是由核心问题1288修复的,GCC应该实现其解决方案,但从错误消息中看起来它没有完全修复。相关文章:
- VS 2015 链接错误 无法构建依赖于 libcurl 的项目
- VS Code C++:不准确的系统包括路径错误(wchar.h,boost/lambda/lambda.hpp)
- 与clang++一起使用的VS代码在构建良好的C++文件中显示错误
- 磁力计代码:C++ vs C - iosstream,矢量 - 错误iostream:没有这样的文件或目录
- VS 2017 社区收到链接器错误,但专业版没有
- 如何知道C2259 VS 2017错误未实现哪种方法?
- C++ VS 错误:<实验/文件系统>提供 std::experimental::文件系统的标头已被Microsoft弃用,将被删除
- 当 lib 已添加到其他依赖项时,如何在 VS 中调试未解析的外部符号错误
- IntelliSense在VS Code中使用Arduino时会引发 #include 错误
- 是 VS 代码 MinGW 与 Win32 中未定义的错误
- VS 2017 错误 C2664 地图插入尝试
- VS-2019 的编译错误
- MFC 对话框属性表用法在 VS 2017 中产生错误,适用于 VS 2013
- VS 2017 构建工具失败,出现错误 MSB4019:找不到导入的项目"D:Microsoft.Cpp.Default.props"
- 将参数传递给 c++ 构造函数时出现 VS 编译错误
- VS Code认为任何文件的第一行都是#include错误
- 未报告的错误VS 2015:十六进制字符说明符
- 指针段错误vs未定义行为
- HYPRE blas构建错误VS 2015
- 编译时错误vs运行时错误