与普通 const 对象不同,我们如何被允许创建一个没有任何初始化器的 const std::vector

use*_*570 4 c++ stl vector language-lawyer

我正在学习std::vectorC++。我了解到aconst std::vector<int>意味着我们不能更改该向量中的各个元素,也不能向其中追加/推回更多元素,即我们只能对元素进行读取访问,这是 a 实体所期望的constconst std::vector但我发现定义 a与定义其他const类型(如等)时有所不同intdouble情况如下所示:

int main()
{
    const int i;   //doesn't compiler as expected: initializer needed here 
    const std::vector<int> vec1 ;  //COMPILES FINE: WHY ISN'T AN INITIALIZER NEEDED HERE?

}
Run Code Online (Sandbox Code Playgroud)

正如我们所看到的,对于const内置类型(例如int),我们必须提供一个初始值设定项。

我的第一个问题是,为什么std::vector. 也就是说,我们如何(为什么)可以省略const vector. 我的意思const vector是我们将无法向其中添加元素,因此vec1现在看来这(实际上)毫无用处。

所以我的第二个问题是有用途vec1吗?我的意思是,由于标准允许这样做,所以他们可能已经考虑过这种情况,并发现这vec1在某些地方可能有用。也就是说,vec1在定义时没有初始化程序的用例有哪些。

Nic*_*las 9

正如我们所看到的,对于const内置类型(例如int),我们必须提供一个初始值设定项。

这是不正确的。您必须确保const对象已初始化

如果您没有为对象提供初始化程序,则该对象将经历默认初始化过程

默认初始化 T 类型的对象意味着:

  • 如果 T 是(可能是 cv 限定的)类类型 ([class]),则考虑构造函数。枚举适用的构造函数 ([over.match.ctor]),并通过重载决策 ([over.match]) 选择最适合初始化器 () 的构造函数。使用空参数列表调用如此选择的构造函数来初始化对象。
  • 如果 T 是数组类型,则每个元素都默认初始化。
  • 否则,不执行初始化。

vector<int>是一个类类型,所以使用第一个选项。将调用默认构造函数来初始化它。

int不是一个类类型。它也不是数组类型。因此,不执行初始化。如果这种情况发生在const对象上,则代码格式错误。

对于初始化const对象,存在进一步的规则:

如果程序要求对 const 限定类型 T 的对象进行默认初始化,则 T 应是 const 默认可构造类类型或其数组。

int根本不是类类型或类类型数组。因此,任何创建具有默认初始化const类型的 -qualified 对象的尝试int都会违反此规则并且格式不正确。

vector<int>恰好遵循-default-constructible的规则const,这就是您的代码可以工作的原因。

至于这个特定的对象是否“有用”,那取决于你。它是一个空vector<int>,不能变得非空。如果这在某些情况下对您有用,那么它就是有用的。