std容器元素的构造正确性

Const-Correctness for Elements of std Containers

本文关键字:正确性 元素 std      更新时间:2023-10-16

以下错误:

vector<const int> vec;

问题是模板类型需要是可赋值的。以下代码编译[EDIT:in Visual Studio 2010],演示了上面的问题:

vector<const int> vec;
vec.push_back(6);
vec[0] += 4;

对于更复杂的类型,这可能是一个严重的问题。

我的第一个问题是,这种行为是否有原因。在我看来,可能会使不允许上述内容的const容器和允许它的非const容器成为可能

第二,有没有一种方法可以使容器以这种方式发挥作用?

第三,这里(对于用户类型)实际发生了什么?我意识到这是一种未定义的行为,但STL是如何编译的呢?

不允许使用std::vector<T const>的原因是,当插入到与开头不同的位置时,向量中的对象可能需要重新排列。现在,成员std::vector<T>::push_back(T const& v)在概念上等同于(省略分配器模板参数,因为它与本讨论无关)

template <typename T>
void std::vector<T>::push_back(T const& v) {
this->insert(this->end(), v);
}

这似乎是它在某些实现中的实现方式。现在,这个操作通常需要移动一些对象,因此T参数需要是可赋值的。MSVC++附带的标准库似乎没有委托操作,而是在push_back()中执行所有必要的处理,即调整阵列大小和在空间不足时适当移动对象。目前还不太清楚T型能够使用push_back()的要求是什么。

原则上,支持T const和中间的insert()操作的容器是可能的,但:在接口中暴露T&时,不需要内部存储为T而不是typename std::remove_const<T>::type。对于像operator[]()这样的操作的const版本,有必要稍微小心一点,因为当T是某种类型S const时,仅使用T const&作为返回类型就会产生类型S const const。在C++2003中,这将是一个错误,在C++2011中,我认为const刚刚崩溃。为了安全起见,您可以使用typename std::add_const<T>::type&