HC4*_*ica 65 c++ const vector c++11
容器需求已从C++ 03更改为C++ 11.虽然C++ 03有一揽子要求(例如复制构造性和向量的可赋值性),但C++ 11定义了每个容器操作的细粒度要求(第23.2节).
因此,只要您只执行某些不需要赋值的操作(构造并且push_back是这样的操作),您可以例如在向量中存储可复制构造但不可赋值的类型(例如具有const成员的结构).; insert不是).
我想知道的是:这是否意味着标准现在允许vector<const T>?我没有看到任何理由它不应该 - const T就像具有const成员的结构一样,是一种可复制构造但不可分配的类型 - 但我可能错过了一些东西.
(让我觉得我可能错过了一些东西的部分原因是,如果你试图实例化vector<const T>,那gcc trunk会崩溃并烧掉,但是vector<T>对于T有const成员的地方来说很好).
Bo *_*son 44
不,我相信分配器要求说T可以是"非const,非参考对象类型".
对于常量对象的向量,您将无法做很多事情.const vector<T>无论如何,a 几乎是一样的.
许多年后,这个快速而肮脏的答案似乎仍然吸引着评论和投票.并不总是.:-)
所以要添加一些适当的参考:
对于我在纸上的C++ 03标准,表31中的[lib.allocator.requirements]部分说:
T, U any type
不是任何类型实际工作.
因此,下一个标准C++ 11 在[allocator.requirements]的详细草案中说,现在表27:
T, U, C any non-const, non-reference object type
这与我最初从记忆中写的内容非常接近.这也是问题所在.
但是,在C++ 14(草案N4296)中,表27现在说:
T, U, C any non-const object type
可能因为参考可能毕竟不是对象类型?
现在在C++ 17(草案N4659)中,表30表示:
T, U, C any cv-unqualified object type (6.9)
因此,不仅const排除了,而且还排除了volatile.无论如何可能是旧的新闻,只是一个澄清.
另请参阅Howard Hinnant的第一手资料,目前正好在下面.
How*_*ant 27
更新
根据我在2011年评论的接受(和正确)答案:
底线:我们没有设计容器
const T.虽然我确实给了它一些想法.我们非常接近于偶然做到这一点.据我所知,目前的症结是一对重载address默认allocator的成员函数:如果T是const,这两个重载具有相同的签名.解决这个问题的一个简单方法是专门化std::allocator<const T>并删除其中一个重载.
随着即将推出的C++ 17草案,在我看来,我们现在已经合法化vector<const T>,而且我也相信我们已经意外地完成了它.:-)
P0174R0消除了address过载std::allocator<T>. P0174R0没有提到支持std::allocator<const T>作为其基本原理的一部分.
更正
在下面的评论中,TC正确地指出address过载已弃用,未被删除.我的错.不推荐使用的成员不会在20.10.9中显示std::allocator,而是在其中定义,而是降级到D.9节.当我发布这个时,我忽略了扫描D章这种可能性.
谢谢你TC的纠正.我打算删除这个误导性的答案,但也许最好把这个纠正留下来,这样也许它会让别人误解我的规范.
即使我们已经对此做出了很好的回答,但我还是决定做出更实际的回答,以表明可以做什么和不能做什么。
所以这不起作用:
vector<const T> vec;
Run Code Online (Sandbox Code Playgroud)
只需阅读其他答案即可了解原因。而且,您可能已经猜到了,这也不起作用:
vector<const shared_ptr<T>> vec;
Run Code Online (Sandbox Code Playgroud)
T不再const,而是vector持有shared_ptr,而不是T。
另一方面,这确实起作用:
vector<const T *> vec;
vector<T const *> vec; // the same as above
Run Code Online (Sandbox Code Playgroud)
但是在这种情况下,const是指向的对象,而不是指针本身(向量存储的对象)。这等效于:
vector<shared_ptr<const T>> vec;
Run Code Online (Sandbox Code Playgroud)
没关系
但是,如果我们将const表达式放在末尾,它现在会将指针变成一个const,因此以下内容将无法编译:
vector<T * const> vec;
Run Code Online (Sandbox Code Playgroud)
我同意,这有点令人困惑,但是您已经习惯了。
小智 5
补充其他答案,另一种方法是使用:
vector<unique_ptr<const T>> vec;
Run Code Online (Sandbox Code Playgroud)
如果您想强制执行,则它仅vec拥有其项目的所有权。或者,如果您想要动态地将项目移入vec并在某些时候将它们移出。
正如指出的那样,指针const的语义可能会产生混淆,但shared_ptr并unique_ptr没有。const unique_ptr<T>是一个常量指针,并且unique_ptr<const T>是一个常量指针,正如你所期望的。