如果未明确定义非POD常量,为什么以下编译?

时间:2017-09-18 20:23:47

标签: c++ c++11

我的印象是所有const成员必须由构造函数显式初始化一次,但在测试之后,似乎只有POD类型必须初始化。无论构造函数中是否提及b,都会编译以下内容:

#include <string>

struct A {
    const int a;
    const std::string b;

    A() : a{} {}
};

示例:http://cpp.sh/36my2

2 个答案:

答案 0 :(得分:2)

这由C ++ 14 [dcl.init] / 7:

涵盖
  

如果程序要求对const限定类型T的对象进行默认初始化,则T应为具有用户提供的默认构造函数的类类型。

在此上下文中,没有为对象提供初始化程序,而是要求默认初始化&#34;。 &#34;用户提供的默认构造函数&#34;表示定义的构造函数可以使用零参数调用,并且该构造函数未设置为=default;

std::string类确实有一个用户提供的默认构造函数。 因此,此规则会阻止您省略a{},但它不会强制您为b提供任何初始值设定项。

答案 1 :(得分:1)

std::string有一个用户提供的默认构造函数,因此默认构造b会给它一个“有意义”的值(它将是一个空字符串)。因此构造函数可以默认隐式初始化它。

然而,

int是一种简单的可构造类型。它的默认构造函数绝对没有,所以a的内容是不确定的,除非在成员初始化列表中显式初始化。列表初始化(使用大括号{}a将在其上执行值初始化,并最终为其定义明确的值0。

必须使用有意义的值初始化成员变量,因为程序之后无法更改它们。这是要求初始化程序背后的基本原理。