STL容器的要求

4

标准是否要求some_container<T>::value_typeT

我问这个问题是因为我正在考虑实现STL兼容的二维动态数组的不同方法之一是让2Darray<T>::value_type成为2Darray_row<T>或类似的类型,其中这个数组将被迭代为一组行(有点简化,我的实际实现允许在3个方向上进行迭代)。


2
实际上,如果你想声明你的模板“是一个容器”,那么要么是因为你想将它传递给一些以容器模板作为模板模板参数的通用代码,要么只是为了缩写定义。在前一种情况下,你可以查看通用代码在命名实例化时实际上需要什么,而在后一种情况下,你可以完全记录你的模板(特别是确保它的迭代器确实是迭代器,这样它们才能与标准算法一起工作),但如果你有疑问,就不要称其为容器 :-) - Steve Jessop
"缩写定义" -- 我的意思是缩写文档,抱歉。 - Steve Jessop
3个回答

5

容器的要求有点奇怪,因为它们实际上并未被任何通用算法使用。从这个意义上说,这并不太重要。

尽管如此,容器的要求是针对接口而不是容器的实例化方式的。即使非模板类也可以符合各种要求,并且实际上确实符合。要求是 value_type 存在;定义取决于容器的实现方式。


它们没有被任何算法使用,但我认为它们可能被插入迭代器使用。(至少,在标准中,它们是我能想到的容器类型实例化另一个模板的唯一位置。) - James Kanze
2
@Angew:所有这些语句都表明X是一个容器,其value_type恰好是T。并没有要求X可以被拼写为some_identifier<T>(对于某个标识符some_identifier),这就是这个问题所涉及的内容。所有的陈述都只是说X是容器名称,其元素类型是T类型,这显然意味着X::value_typeT(有点自证不同) 。 - Dietmar Kühl
@JamesKanze:是的,插入迭代器确实使用了三个签名和一些typedef,它们是众多签名和typedef中的一部分。 - Dietmar Kühl
1
+1,并且我想澄清一下,类型满足容器要求和模板“成为容器”的含义是有区别的。我们谈论std::vector“成为容器”,但实际上我们指的是std::vector<T>对于所有满足容器元素要求(除了bool)的类型T都满足容器要求。 - Steve Jessop
1
@DietmarKühl 我一定误解了问题,抱歉。 - Angew is no longer proud of SO
显示剩余4条评论

2

标准中的§23.2.1中的表96要求容器类X包含类型为T的对象并返回X::value_typeT

因此,如果您的some_container存储类型为T的对象,则value_type必须是T


1
§23.2.4(7)关联式容器满足分配器感知容器(23.2.1)的所有要求,但对于map和multimap,表96中对value_type的要求改为适用于key_type和mapped_type。 - MWid
Dietmar Kühl在这里似乎有一个有效的观点:https://dev59.com/BmrXa4cB1Zd3GeqPCb9Q#dIzjnYgBc1ULPQZFXbWn - Baruch
1
引用的声明(23.2.1第4段)并不需要任何东西!它是一个术语的定义。它所陈述的只是XT之间的关系(即X::value_typeT)。它并没有说明some_type<T>::value_typeT - Dietmar Kühl
@DietmarKühl 谢谢,我明白了。但是value_type不是要求返回容器中存储的对象类型吗?所以对于vector实际上没有选择余地。(问题并没有说T2Darray中存储的对象类型,这是我的错误) - MWid
@MWid:是的,对于std::vector<T>value_type必须是T。通常,你希望value_type是元素的类型,这可能是模板参数,但不需要是任何模板参数之一。 - Dietmar Kühl
显示剩余3条评论

0
要么使用嵌套容器(例如colArray<rowArray<T> >),要么使用单个包装容器(例如2dArray<T>),但不要混合使用它们。嵌套方法允许您在整个过程中使用STL(例如vector<vector<T> >),但可能会令人困惑,并且不允许您使用列迭代器等功能,这似乎是您想要的。 这个SO答案解决了使用ublas的问题,另一个建议使用Boost多维数组
一般来说,如果可以的话,请选择STL或Boost选项。您很难自己编写出同样好的东西。

这更多是一个练习,以学习STL的内部细节。 - Baruch
我仍然会一直使用STL,因为row_type将具有迭代器,并且能够从2Darray中检索列迭代器。但这实际上不是问题的范围,这只是为什么可能想要这样做的一个例子。 - Baruch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接