c++ 底漆说:
只要对象是默认的或 值已初始化。
发生默认初始化
• 当我们定义非静态变量(第 2.2.1 节,第 43 页)或数组(第 3.5.1 节,第 114 页)时 在没有初始化器的块作用域
• 当一个类本身具有类类型的成员时,使用合成的de- 错误构造函数(第 7.1.4,第 262 页)
• 当类类型的成员未在构造函数中显式初始化时 初始化列表(第 7.1.4,第 265 页)
发生值初始化
• 在数组初始化期间,当我们提供的初始值设定项少于大小时 数组的(第 3.5.1 页,第 114 页)
• 当我们定义不带初始化器的局部静态对象时(第 6.1.1 节,第 205 页) • 当我们通过编写表达式显式请求值初始化时 T() 形式,其中 T 是类型的名称(向量构造函数 采用单个参数来指定向量的大小(第 3.3.1 节,第 98 页) 此类参数的值初始化其元素初始值设定项。)
类必须具有默认构造函数才能在这些上下文中使用。最多 这些上下文应该相当明显
class foo{
public :
int data;
foo() = default;
};
int main(){
std::vector<foo> fvec1;
std::vector<foo> fvec2(4,foo(2));
foo f[5]{1,2,4};
std::cout << fvec2[1].data << " " << f[4].data << std::endl;
}
输出:
error: no matching function for call to ‘foo::foo(int)’
std::vector<foo> fvec2(4, foo(2));
^
error: could not convert ‘1’ from ‘int’ to ‘foo’
foo f[5]{1,2,4};
^
但是如果我们删除以下行
foo() = default;
代码有效,虽然使用了合成的默认构造函数,为什么不将默认构造函数声明为默认值,为什么我虽然声明了默认值但没有获得默认行为。
如果可能的话,任何人都可以提供“c++ Primer”所说的上述原因的示例,因为它太令人困惑了。
标准:C++ 20
编译器:g++-12,clang++-15
我们这里发生了一些事情。首先是
foo
,形式为
class foo{
public :
int data;
};
是一个聚合。聚合可以使用
{}
进行初始化,并从 C++20 开始,已扩展为包含 ()
进行初始化。这意味着在
std::vector<foo> fvec2(4,foo(2));
//and
foo f[5]{1,2,4}
您聚合初始化对象。
当您将
foo
更改为 时
class foo{
public :
int data;
foo() = default;
};
您不再拥有聚合,因为您有用户声明的构造函数。这意味着要对其进行值初始化,您需要提供一个构造函数,该构造函数接受构造该类所需的值。您可以通过添加像
这样的构造函数来做到这一点class foo{
public :
int data;
foo() = default;
foo(int data_) : data(data_) {}
};