使用已删除的复制构造函数初始化const引用成员
Initialization of const reference member with deleted copy constructor
这段代码在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};
}
哪一个编译器是对的?
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
您的示例可以简化为
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
}
ar2
在gcc-4.8上初始化失败,出现错误
error: use of deleted function ‘A::A(const A&)’
它在clang3.4和gcc4.9上进行了干净的编译。这是《禁止化学武器公约》第1288号决议的结果。
N3337包含以下用于列表初始化的语言:
§8.5.4/3[dcl.init.list]
T
类型的对象或引用的列表初始化定义如下:
--...
--否则,如果T
是引用类型,则T
被列表初始化,并且引用被绑定到该临时
当然,这意味着ar2
的初始化需要一个可访问的复制构造函数,因此出现了错误。
N3797中的语言发生了变化,其中从包含单个元素的初始值设定项列表进行的初始化优先于上面引用的大小写。
--否则,如果初始化器列表具有类型为
E
的单个元素,并且T
不是引用类型或者其引用类型是与E
相关的引用,则从该元素初始化对象或引用;...
--否则,如果T
是引用类型,则根据引用的初始化类型,T
引用的类型的prvalue临时被复制列表初始化或直接列表初始化,并且引用被绑定到该临时。
因此,gcc 4.9和clang 3.4正在执行问题1288的解决方案,而gcc 4.8则遵循C++11标准中的措辞。
相关文章:
- 如何在旧c++中初始化const-std向量
- 我可以初始化 const 实例,以便我可以将其用作 const 来初始化数组吗?
- 使用 const char* 初始化 const ref 字符串成员时幕后会发生什么
- 如何使用函数的输出初始化 const 数组结构字段?
- 有效地初始化 const std::vector 类成员
- 正在初始化const boost multi_array
- 在类声明中初始化 const 成员变量时在调试模式下出现异常
- 如何在现代C++中用生成器初始化 const 容器?
- 初始化 const 成员的正确方法
- 如何通过头文件中的函数初始化 const int 数组?
- 通过与现有 QHash 连接来初始化 const QHash
- C++ 在头文件或构造函数中初始化 const 类成员变量?
- 在没有构造函数的情况下初始化 const c++ 类
- 如何初始化 const std::vector<MyClass>
- 使用静态方法初始化 const 类字段的做法是好是坏
- 在C++标准中哪里说必须初始化 const 内置类型变量的定义
- 从constructor参数中初始化const多维数组中的const多维数组
- 初始化const 3D数组成员变量
- 在同一构造函数中使用该 const int 初始化 const int 和对象
- 在构造函数中初始化const字段,但首先检查一个参数