C++ 如何使用已删除的复制构造函数(C+;+;11)初始化类数组
关于的现有问题具体涉及C++03。从这个问题中我知道我试图做的事情在C++03中是不允许的,但我认为在C++11中应该是可能的 我有一个不可移动的类(称为Child),我需要在另一个类的构造函数中初始化Child数组(称为Parent)。“不可移动”是指子对象的地址在该对象的生命周期内必须保持不变。正确的方法是什么 使用C++11,我尝试了以下方法:C++ 如何使用已删除的复制构造函数(C+;+;11)初始化类数组,c++,arrays,c++11,gcc,clang,C++,Arrays,C++11,Gcc,Clang,关于的现有问题具体涉及C++03。从这个问题中我知道我试图做的事情在C++03中是不允许的,但我认为在C++11中应该是可能的 我有一个不可移动的类(称为Child),我需要在另一个类的构造函数中初始化Child数组(称为Parent)。“不可移动”是指子对象的地址在该对象的生命周期内必须保持不变。正确的方法是什么 使用C++11,我尝试了以下方法: class Child { public: Child (int x) {} ~Child () {} Child (c
class Child
{
public:
Child (int x) {}
~Child () {}
Child (const Child &) = delete;
};
class Parent
{
public:
Parent () : children {{5}, {7}} {}
private:
Child children[2];
};
这段代码在Clang 3.5.0中编译得很好,但GCC 4.9.1抱怨我试图使用删除的复制构造函数:
test.cc: In constructor ‘Parent::Parent()’:
test.cc:13:35: error: use of deleted function ‘Child::Child(const Child&)’
Parent () : children {{5}, {7}} {}
^
test.cc:7:5: note: declared here
Child (const Child &) = delete;
^
我已经了解了复制初始化和直接初始化之间的区别(例如,我希望通过使用直接初始化避免调用复制构造函数)。我的语法错了吗?这是GCC中的错误吗?或者我正在尝试做的是不可能的?我遇到了一个类似的问题,即此代码
#include <iostream>
class Widget {
public:
Widget(int i) { std::cout << "Ctor " << i << std::endl; }
Widget(const Widget&); // = delete;
};
int main() {
Widget w = 123;
}
#包括
类小部件{
公众:
Widget(inti){std::cout我同意这样的评论,即这似乎是一个GCC错误(报告为)
只有当数组中的类型具有用户定义的析构函数时,它才会编译失败,这对我来说没有意义。在我看来,这是一个clang错误,而不是gcc错误。如果将代码更改为children{Child{5},children{7},clang将无法编译代码
,其行为应与您发布的内容相同。解决方法是使用向量
并放置子对象。g++成功地使用子对象[2]{{5}、{7};
,该版本应与ctor初始值设定项列表中出现相同初始值设定项的版本相同;这两个版本都包含在[dcl.init.list]/3阅读有关初始化的部分,这段代码似乎是正确的;children[2]={{{5},{7}
说children[0]
是从{5}
复制初始化的,即它与Child c={5};
,这在[dcl.init.list]中涵盖再次调用c
的构造函数,该构造函数接受int
(不涉及副本)。@Praetorian:children{Child{5},children{7}
是不同的,我认为,将children{5}
放在大括号内会迫使编译器(名义上)执行创建一个临时对象,然后复制它来初始化数组。创建。我们将看到GCC开发人员所说的话。我认为这并不是真的相关。Widget w=123;
使用复制构造函数,Widget w{123}
是直接初始化。这肯定是另一种情况。在堆栈上创建小部件
需要一个可访问的析构函数,因为它会自动为堆栈对象调用。如果你有一个已删除的析构函数,你就不能在堆栈上创建它。这与问题无关。@JonathanWakely它不是de在我的示例中被删除的structor。很抱歉,您是对的。但情况仍然不同。Widget w=123;
表示Widget w=Widget(123)需要复制构造函数。这是C++的一个众所周知的特性,与C++ 11无关,与这个问题无关。@ JoaNahanWakyi我理解标准的引用部分(在我写这个时候),也谈到OP中的情况。我建议失败的行相当于<代码>父()。:children{Child{5},children{7}{}
然后从临时数组初始化实际数组元素。但是可能我出了什么问题。有时没有析构函数也会失败:@peku33,是的,我在GCC错误报告中给出了一个类似的例子。问题发生在非平凡的析构函数上,而不仅仅是用户定义的析构函数。