C++11 是否允许向量<const T>?

2022-01-23 00:00:00 constants vector c++ c++11

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

因此,您可以例如将可复制构造但不可赋值的类型 - 例如具有 const 成员的结构 - 存储在向量中,只要您只执行某些不需要赋值的操作(构造和 push_back 就是这样操作;insert 不是).

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

(让我觉得我可能遗漏了什么的部分原因是,如果您尝试实例化 vector<const T>,gcc 主干会崩溃并烧毁,但使用 vector<T> 其中 T 有一个 const 成员).

解决方案

不,我相信分配器要求说 T 可以是非常量、非引用对象类型".

你不能用常量对象的向量做很多事情.而且一个 const vector<T> 无论如何都几乎是一样的.

<小时>

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

所以要添加一些适当的参考:

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

<块引用>

T,U 任意类型

并不是说 any 类型确实有效.

因此,下一个标准 C++11 在 [allocator.requirements] 中在草稿中说现在是表 27:

<块引用>

T、U、C 任何非常量、非引用对象类型

这与我最初凭记忆在上面写的非常接近.这也是问题所在.

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

<块引用>

T、U、C 任何非常量对象类型

可能是因为引用毕竟不是对象类型?

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

<块引用>

T、U、C 任何 cv 非限定对象类型 (6.9)

所以不仅排除了const,还排除了volatile.无论如何可能是旧消息,只是一个澄清.

<小时>

另请参阅Howard Hinnant 的第一手资料,目前就在下方.p>

Container requirements have changed from C++03 to C++11. While C++03 had blanket requirements (e.g. copy constructibility and assignability for vector), C++11 defines fine-grained requirements on each container operation (section 23.2).

As a result, you can e.g. store a type that is copy-constructible but not assignable - such as a structure with a const member - in a vector as long as you only perform certain operations that do not require assignment (construction and push_back are such operations; insert is not).

What I'm wondering is: does this mean the standard now allows vector<const T>? I don't see any reason it shouldn't - const T, just like a structure with a const member, is a type that is copy constructible but not assignable - but I may have missed something.

(Part of what makes me think I may have missed something, is that gcc trunk crashes and burns if you try to instantiate vector<const T>, but it's fine with vector<T> where T has a const member).

解决方案

No, I believe the allocator requirements say that T can be a "non-const, non-reference object type".

You wouldn't be able to do much with a vector of constant objects. And a const vector<T> would be almost the same anyway.


Many years later this quick-and-dirty answer still seems to be attracting comments and votes. Not always up. :-)

So to add some proper references:

For the C++03 standard, which I have on paper, Table 31 in section [lib.allocator.requirements] says:

T, U any type

Not that any type actually worked.

So, the next standard, C++11, says in a close draft in [allocator.requirements] and now Table 27:

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

which is extremely close to what I originally wrote above from memory. This is also what the question was about.

However, in C++14 (draft N4296) Table 27 now says:

T, U, C any non-const object type

Possibly because a reference perhaps isn't an object type after all?

And now in C++17 (draft N4659) it is Table 30 that says:

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

So not only is const ruled out, but also volatile. Probably old news anyway, and just a clarification.


Please also see Howard Hinnant's first-hand info, currently right below.

相关文章