std容器元素的正确性

时间:2012-11-18 17:17:26

标签: c++ std

以下是不好的:

vector<const int> vec;

问题是模板类型需要可分配。以下代码编译[编辑:在Visual Studio 2010中],演示了上述问题:

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

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

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

第二,有没有办法让容器以这种方式运作?

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

1 个答案:

答案 0 :(得分:3)

不允许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 constinsert()操作的容器:没有任何内容存储需要T而不是typename std::remove_const<T>::type在界面中暴露T&时。有必要对const - operator[]()等操作版本稍加谨慎,因为当T const&为某种类型T时只使用S const作为返回类型会产生S const const类型。在C ++ 2003中,这将是一个错误,在C ++ 2011中,我认为const刚刚崩溃。为安全起见,您可以使用typename std::add_const<T>::type&