C ++ 11是否允许vector <const t =“”>?</const>

时间:2011-08-05 10:28:17

标签: c++ vector c++11 const

容器要求已从C ++ 03更改为C ++ 11。虽然C ++ 03有一揽子要求(例如复制可构造性和向量的可赋值性),但C ++ 11定义了每个容器操作的细粒度要求(第23.2节)。

结果,您可以例如只要你只执行某些不需要赋值的操作(构造和push_back就是这样的操作),就可以在向量中存储一个可复制构造但不可赋值的类型(例如带有const成员的结构); { {1}}不是。)

我想知道的是:这是否意味着标准现在允许insert?我没有看到任何理由它不应该 - vector<const T>,就像具有const成员的结构一样,是一种可复制构造但不可分配的类型 - 但我可能错过了一些东西。

(让我觉得我可能错过了一些东西的部分原因是,如果你尝试实例化const T,那gcc trunk会崩溃并烧掉,但是对于vector<const T>来说这很好,其中T有一个const成员)

4 个答案:

答案 0 :(得分:40)

不,我相信分配器要求说T可以是“非常量,非参考对象类型”。

对于常量对象的向量,您将无法做很多事情。无论如何,const vector<T>几乎都是一样的。


多年以后,这个快速而肮脏的答案似乎仍然吸引着评论和投票。并不总是。 : - )

所以要添加一些适当的引用:

对于我在纸上的C ++ 03标准,[lib.allocator.requirements]部分的表31说:

  

T, U any type

并非任何类型实际上都有效。

所以,下一个标准C ++ 11在[allocator.requirements]中说in a close draft,现在表27:

  

T, U, C any non-const, non-reference object type

这与我最初在内存中写的内容非常接近。这也是问题所在。

但是,在C ++ 14(draft N4296)中,表27现在说:

  

T, U, C any non-const object type

可能因为参考文件毕竟不是对象类型?

现在在C ++ 17(draft N4659)中,表30显示:

  

T, U, C any cv-unqualified object type (6.9)

因此,不仅const被排除,而且volatile也被排除在外。无论如何可能是旧的新闻,只是一个澄清。


另请参阅Howard Hinnant's first-hand info,目前正好在下面。

答案 1 :(得分:24)

<强>更新

根据我在2011年评论的接受(和正确)答案:

  

结论:我们没有设计容器来容纳const T。虽然我做到了   考虑一下。我们真的很接近这样做   事故。据我所知,目前的关键点是   默认情况下,重载的address成员函数对   allocator:当Tconst时,这两个重载具有相同的重载   签名。一个简单的方法来纠正这个问题就是专注   std::allocator<const T>并删除其中一个重载。

随着即将推出的C ++ 17草案,我觉得我们现在已经合法化了vector<const T>,我也相信我们已经意外地完成了。 : - )

P0174R0address中移除了std::allocator<T>重载。 P0174R0未提及支持std::allocator<const T>作为其基本原理的一部分。

<强>校正

在下面的评论中。正确地指出address重载已弃用,未删除。我的错。被弃用的成员不会出现在20.10.9中,std::allocator被定义,而是被降级到D.9部分。当我发布这个可能性时,我忽略了扫描D章的这种可能性。

谢谢T.C.为了纠正。我打算删除这个误导性的答案,但也许最好还是留下这个更正,以便它可能会让别人误解我的规范。

答案 2 :(得分:3)

尽管我们已经对此有了非常好的答案,但我还是决定用更实际的答案来说明可以做什么和不能做什么。

所以这不起作用:

vector<const T> vec; 

请阅读其他答案以了解原因。而且,正如您可能已经猜到的那样,这也不会起作用:

vector<const shared_ptr<T>> vec;

T不再是const,但vector持有shared_ptr,而不是T

另一方面,这个 工作:

vector<const T *> vec;
vector<T const *> vec;  // the same as above

但在这种情况下,const是指向的对象,而不是指针本身(这是向量存储的对象)。这相当于:

vector<shared_ptr<const T>> vec;

哪个好。

但是如果我们将const放在表达式的末尾,它现在将指针转换为const,因此以下内容将无法编译:

vector<T * const> vec;

有点令人困惑,我同意,但你已经习惯了。

答案 3 :(得分:2)

补充其他答案,另一种方法是使用:

vector<unique_ptr<const T>> vec;

如果您希望强制执行仅vec拥有其所有权的所有权。或者,如果您想要动态移动项目vec,并在某个时候将其移出。

正如所指出的,指针const语义可能令人困惑,但shared_ptrunique_ptr不是。 const unique_ptr<T>是一个const指针,unique_ptr<const T>是一个const指针,如你所料。