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

How is it that we're allowed to create a const std::vector without any initializer unlike normal const objects

我正在学习 C++ 中的 std::vector。我 learnt const std::vector<int> 意味着我们不能更改该向量中的单个元素,也不能 append/push_back 更多元素进入它,即我们只能读取元素,这是预期来自 const 的实体。但是我发现定义 const std::vector 与定义其他 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?

}

正如我们所见,对于 const 内置类型(如 int),我们必须提供初始化程序。

我的第一个问题是 为什么 std::vector 不是这种情况。也就是说,我们如何(为什么)可以省略 const vector 的初始值设定项。我的意思是 const vector 意味着我们将无法向其中添加元素,所以看起来这个 vec1 现在(实际上)没用了。

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

As we can see that for a const built in type(like int), we must provide an initializer.

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

如果你do not provide an initializer for an object, that object will undergo the process of default initialization:

To default-initialize an object of type T means:

  • If T is a (possibly cv-qualified) class type ([class]), constructors are considered. The applicable constructors are enumerated ([over.match.ctor]), and the best one for the initializer () is chosen through overload resolution ([over.match]). The constructor thus selected is called, with an empty argument list, to initialize the object.
  • If T is an array type, each element is default-initialized.
  • Otherwise, no initialization is performed.

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

int 不是 class 类型。它也不是数组类型。因此,不执行初始化。如果这发生在 const 对象上,代码是 ill-formed.

对于初始化 const 对象,存在更多规则:

If a program calls for the default-initialization of an object of a const-qualified type T, T shall be a const-default-constructible class type or array thereof.

int 根本不是 class 类型或 class 类型的数组。因此,任何使用 default-initialization 创建 int 类型的 const 限定对象的尝试都违反了此规则,并且是 ill-formed.

vector<int> 恰好 follow the rules of const-default-constructible,这就是您的代码有效的原因。

至于这个特定对象是否“有用”,由您决定。它是一个空 vector<int>,无法创建 non-empty。如果这在某些情况下对你有用,那就有用了。