ale*_*cov 9 c++ gcc c++11 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); }
Run Code Online (Sandbox Code Playgroud)
和:
#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); }
Run Code Online (Sandbox Code Playgroud)
最新的Clang和MSVC编译器都接受这两个程序.GCC 5及以后接受第一个程序,但拒绝第二个程序,声称invalid cast of an rvalue expression of type 'int' to type 'int&'.
这是GCC的错误吗?还是这的确之间的差异T{},并T()在上述背景下(因此臭虫锵和MSVC)?
编辑:
问题可以缩小到以下简单的摘录:
int i; (int&){i};
Run Code Online (Sandbox Code Playgroud)
和
int i; (int&)(i);
Run Code Online (Sandbox Code Playgroud)
有两个不同的问题:
T{x}应该如何为参考类型做T.目前[expr.type.conv]/1表示它创建了一个类型的prvalue T,这对于引用类型来说是无意义的.这是核心问题1521.T{x}为了引用类型T粗略地做T __tmp{x};,然后产生等价的static_cast<T>(__tmp)(所以对于右值引用的xvalue T和对于左值引用的左值T).但是,发布的C++ 11搞砸了引用列表初始化的规范,使它始终创建一个临时的.结果是int i; int &r{i};编译失败,因为它会尝试绑定r到临时副本i,这显然是无稽之谈.这是由核心问题1288修复的,其解析GCC应该实现,但从错误消息看起来它并没有完全修复.