假设我们有这样的代码:
class A {
public:
A() = default;
A(const A&) = delete;
~A() = default;
};
class B {
public:
B() : a{} { }
A a[1];
};
int main()
{
B b;
}
此代码在最新的 GCC 9.2、叮当 9.2 和 MSVC 19.22 上编译。
但当我将默认析构函数更改为~A(){}
GCC返回错误使用删除的函数'A::A(const A
当我编写
A
的复制构造函数时,GCC会编译,但在运行时从未调用此构造函数。GCC需要复制构造函数做什么?是GCC错误吗?(我在GodBolt.org上尝试了所有GCC版本,同样的错误。)
这是一个海湾合作委员会的错误。
B
的默认构造函数使用聚合初始化来初始化不带初始值设定项的。[dcl.init.aggr]/8:
如果列表中的initializer子句比非联合聚合中的元素少,则每个未显式初始化的元素都按如下方式初始化:
>
如果元素有一个默认的成员初始值设定项([class.mem]),那么该元素将从该初始值设定值设定项初始化。
否则,如果元素不是引用,则从空的初始值设定项列表 ([dcl.init.list]) 复制初始化该元素。
否则,程序格式不正确。
[...]
所以< code>a[0]
是从< code>{}复制初始化的,这是复制列表初始化。这可能是GCC开始感到困惑的地方——复制初始化不一定涉及复制构造函数。
[dcl.init.list]/3.4:
T类型的对象或引用的列表初始化定义如下:
> < li>
[...]
否则,如果初始值设定项列表没有元素,并且
T
是具有默认构造函数的类类型,则该对象将进行值初始化。
[...]
因此,直接使用
A
的默认构造函数。不涉及复制构造函数。也不是琐事。
如果您担心C11和C17之间的差异,N3337[dcl.init.aggr]/7:
如果列表中的初始值设定项子句少于聚合中的成员数,则每个未显式初始化的成员都应从空的初始值设定项列表 ([dcl.init.list]) 初始化。[...]
这里甚至不涉及复制初始化。和N3337 [dcl.init.list]/3.1:
T
类型的对象或引用的列表初始化定义如下:
>
如果初始值设定项列表没有元素,并且
T
是具有默认构造函数的类类型,则对象是值初始化的。
[...]
没有变化。
问题内容: 我最近刚与Python中的一个错误作斗争。那是那些愚蠢的新手错误之一,但是它让我思考了Python的机制(我是C ++的老程序员,是Python的新手)。我将列出错误的代码并解释如何解决该问题,然后我有两个问题。 场景:我有一个叫做A的类,它有一个字典数据成员,下面是其代码(当然这是简化的): 使用此代码的类为B类: 请注意,每次调用都会初始化类A的新“干净”实例,并在添加前后打印字典
在C++98标准里,只有static const声明的整型成员能在类内部初始化,并且初始化值必须是常量表达式。这些限制确保了初始化操作可以在编译时期进行。例如: int var = 7; class X { static const int m1 = 7; // 正确 const int m2 = 7; // 错误:无static static int m3 =
我正在尝试为大学的一个项目和几个学生一起建立一个Springmvc应用程序,这是一本基于网络的烹饪书。 虽然Hello World工作正常,但我们使用hibernate存储数据的代码出现了一些困难的异常。 域类: 服务类: 控制器类: 我们使用基于eclipse的Spring工具包sdk并在启动过程中获得以下异常: VMware vFabric tc Runtime 2.9.3.Release/7
初始化类成员的确切时间? 在下面的代码中: B&C类的对象是什么时候创建的?并且它是否保证被创建? 一个专业的app到底该不该用这样的代码?
考虑以下代码: GCC v6.1编译它,叮当声3.8拒绝它,错误如下: 2:错误:没有成员名为'foo'在'U' struct S{静态constexpr int bar=T::foo;}; 哪个编译器是对的? 会不会是因为在我们尝试在中使用它时不是一个完整的类型? 在这种情况下,它应该被认为是GCC的错误,但我想知道我是否正确之前在错误跟踪器上搜索/打开问题… 编辑 与此同时,我已经向GCC打开