我正在学习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>
,不能使其非空。如果它在某些情况下对你有用,那么它就是有用的。