可以定义一个结构
(a)没有用户定义的构造函数,以及(b)无法生成默认构造函数。例如,下面的Foo
:
struct Baz
{
Baz(int) {}
};
struct Foo
{
int bar;
Baz baz;
};
您仍然可以使用聚合初始化创建Foo的实例:
Foo foo = { 0, Baz(0) };
我的普通编译器(VS2012)将勉强接受这一点,但它提出了两个警告:
警告C4510:'Foo':无法生成默认构造函数。
警告C4610:结构“Foo”永远不能实例化-需要用户定义的构造函数
当然,我刚刚证明了警告#2是错误的——您仍然可以使用聚合初始化来实例化它。我试过的在线编译器很乐意接受上述内容,所以我猜VS2012只是因为这个警告过于激进了。但我想确定的是,这段代码可以吗,或者它在技术上违反了标准中一些模糊的部分?
这实际上不是聚合初始化,它是统一的,直到最近才被VS支持。这个警告只是他们没有正确地更新它,以反映该类型现在可以统一初始化。
聚合可能没有用户定义的非默认非删除构造函数,聚合UDT的规则是每个成员也必须是聚合。因此,Baz不是一个集合,直接结果是,Foo也不是。
该标准明确允许像[12.1p4]中的Foo
这样的情况:
[...] 如果类X没有用户声明的构造函数,则没有参数的构造函数将隐式声明为默认[…]在以下情况下,类X的默认默认构造函数被定义为已删除:
[...]
[...]
Baz没有默认构造函数,因此上面强调的部分适用(emphasis mine)。
此类案件没有“未定义”或“格式错误”的地方。隐式声明的默认构造函数定义为deleted,仅此而已。你可以明确地做同样的事情,它仍然是有效的。
集料的定义在[8.5.1p1]中。对于C 14,它是:
聚合是一个数组或类(第9条),没有用户提供的构造函数(12.1),没有私有或受保护的非静态数据成员(第11条),没有基类(第10条),没有虚拟函数(10.3)。
“无用户提供”部分允许您对所有可能隐式声明的构造函数(使其成为用户声明的,但不是用户提供的)使用=删除,并且该类仍然是一个聚合,允许您对其使用聚合初始化。
至于警告C4610,我之前遇到过并报告过。正如你所见,它已经在即将到来的VC版本中修复。
值得一提的是,我在错误报告中使用的示例直接取自标准,在标准中,它被视为格式良好的([12.2p5.4]:
struct S { int mi; const std::pair<int,int>& mp; };
S a { 1, {2,3} };
这与您的情况类似,但在这里,隐式声明的默认构造函数被定义为已删除,因为该类具有没有初始化程序的引用类型的非静态成员。
当然,这只是一个例子,但我认为这是一个额外的迹象,表明这些案例没有错。
参加以下课程: 由于Foo(std::stringbar_, intbaz_=7);是我唯一的构造函数,编译器不应该为我实现默认构造函数,对吗?我认为我可以构造这个类的唯一两种方法是: 然而,为什么这是可能的? 当唯一的公共构造函数要求其第一个参数具有值时,我不理解如何默认构造类。将默认构造函数设为私有或尝试C 11删除它,没有什么区别。这是怎么发生的 http://ideone.com/CL7I
问题内容: 我有一条记录,想要向其中添加默认构造函数。 但是它创建了带参数的构造函数。 我们如何向记录添加默认构造函数? 问题答案: 为了分裂头发,您永远无法定义默认构造函数,因为在没有定义构造函数的情况下,编译器会生成默认构造函数,因此根据定义,任何定义的构造函数都不是默认构造函数。 如果希望记录具有无参数构造函数,则记录确实允许添加额外的构造函数或工厂方法,只要调用将所有记录字段作为参数的“规
似乎一个向量会检查move构造函数是否标记为noexcept,然后再决定重新分配时是移动还是复制元素。默认的移动构造函数是否定义为noexcept?我看到了以下文档,但它没有指定这一点。http://en.cppreference.com/w/cpp/language/move_constructor 隐式声明移动构造函数 如果没有为类类型(struct,类或联合),并且以下所有都是真的:没有用户
我有一个记录,想添加默认构造函数。 但是它创建了带有参数的构造函数。 我们如何将默认构造函数添加到记录中?
问题内容: 默认构造函数到底是什么?你能告诉我以下哪个是默认构造函数,它与其他构造函数有何不同? 问题答案: 他们都不是。如果定义,则不是默认值。 除非你定义另一个构造函数,否则默认构造函数是自动生成的无参数构造函数。任何未初始化的字段都将设置为其默认值。对于你的榜样,它看起来像这样假设的类型String,int以及int,那类本身是公共的: 这与 完全没有构造函数。但是,如果定义至少一个构造函数
问题内容: 我知道我在这里问一些严重的101问题… 我有一些课,还有一个延伸课。在我有一个构造函数,它接受一组参数,并对其字段进行设置。派生类(例如)通常不需要进行修改。现在我的IDE给我 “ Foo中没有默认的构造函数” 。从一点点谷歌搜索,这似乎是因为“构造函数没有继承”。因此,一切都很好,但是我现在如何使它工作而不在每个派生类中复制此构造函数?我假设有一个更合理的方法? 问题答案: 使用构造