如何允许我们创建一个 const std::vector 而没有任何初始值设定项,这与普通的 const 对象不同



我正在学习c++中的std::vector。我了解到,const std::vector<int>意味着我们不能改变该向量内的单个元素,也不能追加/推回更多的元素,即,我们只有对元素的读访问权限,这是const实体所期望的。但我发现在定义const std::vector时比定义其他const类型(如int,double等)有所不同。情况如下:

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的用例是什么?

可以看到,对于const内置类型(如int),必须提供初始化式。

这是错误的。必须确保const对象初始化

如果不为对象提供初始化式,该对象将经历默认初始化过程:

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

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

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

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

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

如果程序调用const限定类型T的对象的默认初始化,则T应为const默认可构造类类型或其数组。

int根本不是类类型或类类型数组。因此,任何使用默认初始化创建int类型的const限定对象的尝试都违反了该规则,并且是病态的。

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

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

最新更新