std容器元素的正确性

ima*_*ett 5 c++ std

以下是坏事:

vector<const int> vec;
Run Code Online (Sandbox Code Playgroud)

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

vector<const int> vec;
vec.push_back(6);
vec[0] += 4;
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

Die*_*ühl 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);
}
Run Code Online (Sandbox Code Playgroud)

这似乎是它在某些实现上的实现方式。现在,此操作通常需要移动某些对象,因此参数T需要可分配。似乎 MSVC++ 附带的标准库不会委托操作,而是执行所有必要的处理,即在push_back(). 目前尚不清楚T能够使用的类型有哪些要求push_back()

T const原则上,支持两者和insert()中间操作的容器是可能的,但是:没有什么需要内部存储T而不是在接口中typename std::remove_const<T>::type暴露 a 。T&有必要对const操作的 -version小心一点,因为当is 某种类型operator[]()用作T const&返回类型时,就会产生 type 。在 C++ 2003 中这将是一个错误,在 C++ 2011 中我认为它们只是崩溃了。为了安全起见,你可以使用.TS constS const constconsttypename std::add_const<T>::type&