我有编译器:
g++ (Ubuntu4.8.4-2 ubuntu1~14.04.1) 4.8.4
2015 ver。14.0(视觉C++ 2015)
源代码:
#include <queue>
class C
{
};
class B
{
public:
// assignment and copy prohibited
B(const B&) = delete;
B& operator=(const B&) = delete;
B(int v1, int v2) : m_V1(v1), m_V2(v2) {}
private:
int m_V1;
int m_V2;
std::queue<C> m_Queue;
};
class A
{
public:
// assignment and copy prohibited
A(const A&) = delete;
A& operator=(const A&) = delete;
A(int p1, int p2) : arrB{ {p1+1, p2+2}, {p1+3, p2+4}, {p1+5, p2+6} } { }
private:
B arrB[3];
};1)如果我将g++与
std::queue<C> m_Queue;我得到以下错误:
make
g++ -std=c++11 -c test.cpp
test.cpp: In constructor ‘A::A(int, int)’:
test.cpp:29:70: error: use of deleted function ‘B::B(const B&)’
A(int p1, int p2) : arrB{ {p1+1, p2+2}, {p1+3, p2+4}, {p1+5, p2+6} } { }
^
test.cpp:11:3: error: declared here
B(const B&) = delete;
^
make: *** [test.o] Error 12)如果我使用g++并注释行
//std::queue<C> m_Queue;或者在2015中使用这两种变体(注释和不注释),我不会遇到任何错误。
为什么?
更新:
列表初始化使用直接列表初始化或复制列表初始化。
8.5.4列表-初始化 1列表-初始化是从大括号内的列表中初始化对象或引用.这样的初始化器称为初始化程序列表,列表的逗号分隔的初始化器-子句称为初始化程序列表的元素。初始化程序列表可能为空。列表初始化可以在直接初始化或复制初始化上下文中进行;直接初始化上下文中的列表初始化称为直接列表初始化,副本初始化上下文中的列表初始化称为复制列表初始化。
但我不明白在我的情况下要使用什么样的初始化。我认为应该根据initialization直接使用列表初始化。
更新2:
8.5.1聚合dcl.init.aggr 1聚合是一个数组或一个类(第9条),没有用户提供的构造函数(12.1),没有私有或受保护的非静态数据成员(第11条),没有基类(第10条),也没有虚拟函数(10.3)。 当聚合被初始化程序列表初始化(如8.5.4中所指定)时,初始化程序列表的元素将作为聚合成员的初始化器,以增加下标或成员顺序。每个成员都从相应的初始化器-子句中复制初始化。
聚合是一个数组和每个成员都是复制初始化的-应答?
但这并不能解释为什么在对行进行注释时没有错误地编译:
//std::queue<C> m_Queue;发布于 2016-04-06 17:16:33
使用提供的代码,我无法在g++中再现您对B中声明的队列的注释/取消注释的奇怪行为。无论队列是否被注释掉,我在g++上都会得到相同的错误。
但是,您正在获得的编译错误与我在代码测试中得到的相同。此错误的原因是您已显式删除了B的复制构造函数。错误消息直接指向B的复制构造函数:B(const B&) = delete;
有关更多细节,请参见这里的答案:https://stackoverflow.com/a/14543600/1456187
至于您问题的第二部分,我只能进行猜测,因为我手头没有Microsoft编译器的副本。我最好的猜测是,Microsoft编译器允许初始化B数组,因为它们是在适当的位置构建的。尽管如此,这似乎是在面对03年规格的标准。
https://stackoverflow.com/questions/36454463
复制相似问题