[英]Initialization of const reference member with deleted copy constructor
This code, with a const A& a
member in B
, where A
has a deleted copy constructor, doesn't compile in GCC 4.8.1, but it works OK in clang 3.4: 这个代码在
B
有一个const A& a
成员,其中A
有一个删除的拷贝构造函数,它不能在GCC 4.8.1中编译,但它在clang 3.4中工作正常:
class A {
public:
A() = default;
A(const A&) = delete;
A& operator=(const A&) = delete;
};
class B{
public:
B(const A& a)
: a{a}
{ }
private:
const A& a;
};
int main()
{
A a{};
B b{a};
}
Which one of the compilers is right? 哪一个编译器是对的?
The error in GCC is: GCC中的错误是:
prog.cpp: In constructor ‘B::B(const A&)’:
prog.cpp:11:14: error: use of deleted function ‘A::A(const A&)’
: a{a}
^
prog.cpp:4:5: error: declared here
A(const A&) = delete;
^
Ideone: http://ideone.com/x1CVwx Ideone: http ://ideone.com/x1CVwx
Your example can be reduced to 你的例子可以简化为
class A {
public:
A() = default;
A(const A&) = delete;
A& operator=(const A&) = delete;
};
int main()
{
A a{};
A const& ar1(a);
A const& ar2{a}; // fails on gcc 4.8
}
The initialization of ar2
fails on gcc-4.8 with the error ar2
的初始化在gcc-4.8上失败并出现错误
error: use of deleted function ‘A::A(const A&)’
It compiles cleanly on clang3.4 and gcc4.9. 它在clang3.4和gcc4.9上完全编译。 This is the result of the resolution to CWG issue 1288 .
这是CWG 第1288号决议的解决结果。
N3337 contains the following language for list-initialization : N3337包含以下用于列表初始化的语言:
§8.5.4/3 [dcl.init.list] §8.5.4/ 3 [dcl.init.list]
List-initialization of an object or reference of type
T
is defined as follows:列表初始化对象或类型
T
引用定义如下:
—...
-
...
— Otherwise, ifT
is a reference type, a prvalue temporary of the type referenced byT
is list-initialized, and the reference is bound to that temporary- 否则,如果
T
是引用类型,则由T
引用的类型的prvalue临时列表进行列表初始化,并且引用绑定到该临时类型
This, of course, means that the initialization of ar2
requires an accessible copy-constructor, hence the error. 当然,这意味着
ar2
的初始化需要一个可访问的拷贝构造函数,因此错误。
The language has changed in N3797, where the initialization from an initializer list containing a single element takes precedence over the case quoted above. N3797中的语言已更改,其中包含单个元素的初始化列表的初始化优先于上面引用的情况。
— Otherwise, if the initializer list has a single element of type
E
and eitherT
is not a reference type or its referenced type is reference-related toE
, the object or reference is initialized from that element;- 否则,如果初始化列表具有
E
类型的单个元素且T
不是引用类型或其引用类型与E
引用相关,则从该元素初始化对象或引用;...
— Otherwise, ifT
is a reference type, a prvalue temporary of the type referenced byT
is copy-list-initialized or direct-list-initialized, depending on the kind of initialization for the reference, and the reference is bound to that temporary.-否则,如果
T
是引用类型,一个prvalue临时被引用的类型的T
是副本列表初始化或直接列表初始化,根据其种类初始化为基准,参考绑定到临时。
So gcc 4.9 and clang 3.4 are implementing the resolution of issue 1288, while gcc 4.8 is following the wording in the C++11 standard. 所以gcc 4.9和clang 3.4正在实现问题1288的解决方案,而gcc 4.8遵循C ++ 11标准中的措辞。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.