我有编译器:
g ++(Ubuntu 4.8.4-2ubuntu1~14.04.1)4.8.4
Microsoft Visual Studio 2015版。 14.0。 (Visual 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 1
2)如果我使用g ++并注释该行
//std::queue<C> m_Queue;
或者我在Microsoft Visual Studio 2015中使用这两种变体(注释与否)我没有收到任何错误。
为什么?
更新
列表初始化使用直接列表初始化或复制列表初始化。
8.5.4列表初始化
1列表初始化是从braced-init-list初始化对象或引用。这样的初始化器 被称为初始化列表,并以逗号分隔 list的initializer-clause称为。的元素 初始化列表。初始化列表可以为空。 列表初始化可以在直接初始化或 copyinitialization contexts;列表初始化在 直接初始化上下文称为直接列表初始化和 调用复制初始化上下文中的列表初始化 复制列表初始化。
但我不明白在我的情况下使用什么样的初始化。我认为应该根据http://en.cppreference.com/w/cpp/language/list_initialization
使用直接列表初始化更新2:
8.5.1聚合[dcl.init.aggr]
1聚合是一个数组或类(第9条),没有用户提供的构造函数(12.1),没有私有或者 受保护的非静态数据成员(第11条),没有基类(子句 10),没有虚函数(10.3)。按指定的初始化列表初始化聚合时 在8.5.4中,初始化列表的元素被视为 增加下标的聚合成员的初始化程序 或会员订单。每个成员都是从中复制初始化的 相应的初始化条款。
聚合是数组,每个成员都是复制初始化 - 回答?
但是,这并不能解释为什么在评论该行时编译没有错误:
//std::queue<C> m_Queue;
答案 0 :(得分:0)
使用提供的代码我无法使用g ++重现您在B中声明的队列的注释/取消注释的奇怪行为。无论队列是否被注释掉,我都会在g ++上得到相同的错误。
但是,您获得的编译错误与我在代码测试中得到的错误相同。此错误是由于您已明确删除了B的复制构造函数。错误消息直接指向B的复制构造函数:B(const B&) = delete;
有关详情,请参阅此答案:https://stackoverflow.com/a/14543600/1456187
关于你问题的第二部分,我只能冒险猜测,因为我没有微软编译器的副本。我最好的猜测是,Microsoft编译器允许Bs数组的初始化,因为它们是在适当的位置构建的。尽管如此,这似乎与“03规范”中的标准一样。