简体   繁体   English

使用已删除的复制构造函数初始化const引用成员

[英]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, if T is a reference type, a prvalue temporary of the type referenced by T 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 either T is not a reference type or its referenced type is reference-related to E , the object or reference is initialized from that element; - 否则,如果初始化列表具有E类型的单个元素且T不是引用类型或其引用类型与E引用相关,则从该元素初始化对象或引用; ...
— Otherwise, if T is a reference type, a prvalue temporary of the type referenced by T 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.

相关问题 在引用初始化中使用已删除的复制构造函数复制初始化 - Copy initialization with deleted copy constructor in reference initialization 复制构造函数初始化初始化列表中的引用成员会导致指针悬空 - Copy constructor initialize a reference member in initialization list causes dangling pointer C ++如果值来自成员变量,则复制​​初始化和const引用初始化之间存在差异 - C++ Difference between copy initialization and const reference initialization if value comes from member variable 常量类成员副本构造函数 - Const Class Member Copy Constructor 没有默认构造函数和已删除的复制构造函数初始化的对象的类成员数组 - Class member array of objects without default constructor and deleted copy constructors initialization const成员引用的值初始化 - value-initialization of a const member reference 初始化列表中const引用成员的初始化 - Initialization of const reference member in initializer list 委托复制构造函数和const数据初始化 - Delegating copy constructor and const data initialization 使用const向量成员复制类的构造函数 - Copy constructor of a class with a const vector member 如何处理const对象中非const引用成员的初始化? - How to deal with initialization of non-const reference member in const object?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM