C ++ 11允许vector <const T>吗?
容器需求已经从C ++ 03改为C ++ 11。 虽然C ++ 03具有一揽子要求(例如,向量的复制可构造性和可分配性),但是C ++ 11在每个容器操作(第23.2节)上定义了细粒度的要求。
因此,只要你只执行某些不需要赋值的操作,就可以将一个可复制但不能赋值的types(比如带有const成员的结构)存储在一个向量中(构造和push_back
就是这样的操作; insert
不)。
我想知道的是:这是否意味着标准现在允许vector<const T>
? 我没有看到任何理由不应该 – const T
,就像一个具有const成员的结构,是一个复制可构造但不可转让的types – 但我可能错过了一些东西。
(使我想我可能错过了一些东西的部分原因是,如果尝试实例化vector<const T>
,gcc trunk将崩溃并烧毁,但对于T有const成员的vector<T>
则没有问题。
不,我相信分配器要求说T可以是一个“非常量,非引用对象types”。
你不能用一个常量对象的vector做很多事情。 而一个const vector<T>
几乎是一样的。
更新
根据我在2011年评论的接受(和正确)答案:
底线:我们没有devise容器来保存
const T
虽然我确实给了一些想法。 我们真的很接近,因为意外。 就我所知,当前的关键点是默认分配器中的一对重载address
成员函数:当T
是const
,这两个重载具有相同的签名。 一个简单的方法来纠正这将是专门化std::allocator<const T>
和删除重载之一。
随着即将到来的C ++ 17草案,在我看来,我们现在已经合法化了vector<const T>
,而且我也相信我们意外地做了这个。 🙂
P0174R0从std::allocator<T>
删除address
重载。 作为其基本原理的一部分, P0174R0没有提到支持std::allocator<const T>
。
更正
在下面的注释中,TC正确地注意到, address
过载不被使用 ,不被移除。 我的错。 不推荐使用的成员在20.10.9中没有出现在std::allocator
被定义的地方,而是被转移到了D.9节。 当我发布这个消息的时候,我忽略了扫描D章的可能性。
谢谢TC的更正。 我打算删除这个误导性的答案,但也许最好留下这个纠正,以便可能会让别人不像我那样误读规范。
尽pipe我们已经有了非常好的答案,但我决定用更实际的答案来expression什么是可以做什么,做什么做不到的。
所以这不起作用:
vector<const T> vec;
只要阅读其他答案来理解为什么。 而且,正如你可能已经猜到的那样,这也是行不通的。
vector<const shared_ptr<T>> vec;
T
不再是const
,而vector
是持有shared_ptr
s,而不是T
s。
另一方面,这是行得通的:
vector<const T *> vec; vector<T const *> vec; // the same as above
但在这种情况下,const是指向的对象,而不是指针本身(这是vector存储的内容)。 这将相当于:
vector<shared_ptr<const T>> vec;
这很好。
但是如果我们把const
放在expression式的末尾,它现在把指针变成一个const
,所以下面的代码不会编译:
vector<T * const> vec;
有点混乱,我同意,但你已经习惯了。