flat_map是STL容器吗?

3
在C++23的草案中,flat_map类型的设计中,flat_map::reference类型被定义为pair<const key_type&, mapped_type&>,即它不是对flat_map::value_type = pair<key_type, mapped_type>的引用。(这似乎是强制性的,因为键和值不是作为一对存储,而是在两个单独的容器中存储。) 因此,迭代器必须是某个代理类。 这让我想到:一个flat_map实际上是否还是STL容器,类似于std::vector<bool>不是一个?

“STL”是一个非常古老的库(标准模板库),它被纳入了C++98标准库。后来是否添加到STL的标准部分了呢?没有。它是否是标准库的一部分,是的。 - Jesper Juhl
@JesperJuhl 这在历史意义上是正确的,但现在它变得更加模糊。在WG21讨论的背景下,“STL”可能表示Stephan T. Lavavej,他是microsoft/STL的维护者。后者是当前ISO C++标准库的最新实现,如果我没记错,STL先生强烈坚持使用这个名称。 - FrankHB
2个回答

3
标准在[container.reqmts]中定义了什么是“容器”。其中要求之一

typename X::reference

  • 结果:T&
所以,是的,std::flat_map不是一个容器。
但它从来没有声称过;它是“容器适配器”

flat_­map是一个容器适配器...

请注意,与std::stack/queue/priority_queue一样,std::flat_set/map采用容器类型作为模板参数。
还应该注意的是,虽然它们不是容器,但它们是由C++20范围库概念定义的范围。 C++20范围概念允许代理范围,其中reference类型不必是value_type&

1
标准规定:“flat_map符合容器的所有要求。”但这并不完全准确,是吗?我对标准中的这一声明感到有些不确定。 - HarryLeong

1
P2767R0的作者在此。这些都是一些追根究底的问题,就像有多少天使能在针尖上跳舞一样,所以虽然我会提出我自己的追根究底的答案,请理解我并不认为其他人的不同答案一定是错误的。实际上,这些问题对实践来说都是同样无关紧要的。
(1)flat_map本身(类模板)不是一个容器,而是一个容器适配器。即使vector也不是一个容器,它只是用来生成容器的模板。在我的观点中,“容器适配器”是一个用来生成容器的模板,其中一个模板参数本身就是一个容器。可以将其与“迭代器适配器”(以及范围中的“视图适配器”)的使用进行比较。{{link1:“类模板reverse_iterator是一个迭代器适配器,”}}但是reverse_iterator<int*>类型的对象(简单地说)是一个迭代器。flat_set是一个容器适配器;flat_set<int>类型的对象(简单地说)是一个容器。
注意[vector.overview]并没有说“类模板 vector 是一个序列容器...”; 它说的是“一个 vector 是一个序列容器…”也就是说,某个特定类型的vector对象(简单地)是一个容器。
"但是[sequences.general]说,‘头文件<array><deque><forward_list><list><vector>定义了满足序列容器要求的类模板!’你怎么解释你声称类模板不是容器的说法呢?"
"嗯,你肯定同意<array>并没有定义任何满足序列容器要求的类模板,对吧?我们可以讨论一下vector<bool>,但是array绝对不是一个容器。所以那句话本身就是错误的。"
"(与此同时,我今天才知道C++23的[vector.bool]/8暗示用户可以为vector<bool, A>提供“程序定义的特化”。谁知道这样的特化可能会做些什么呢!)"
(2) 就我而言,flat_map<int, int> 是一个容器。正如您观察到的,[flat.map]/2 明确指出 flat_map "满足所有容器的要求"。当然,一方面它似乎显然没有满足 X::reference 的要求... 但另一方面,标准文件 它满足 所有 的要求!必须有些权衡的地方;我认为假设 C++98 时代的 [container.reqmts] 与 C++23 的实际不同,而不是假设 C++23 时代的 [flat.map] 不同,这样的假设对现代可能的代理引用类型更合理。只需要有人更新 [container.reqmts],以处理现代可能的代理引用类型的情况。

有人只需要更新[container.reqmts]... 这是一个很好的观点,但它也意味着我们不能完全依赖C++标准。那么,符合所有容器要求的容器到底值得多少呢? 我可能相信了一个错误的概念,即标准是一种没有错误的数学真理(这其实是有道理的,因为C++是一种用于确定性计算机的语言)。 - tommsch
"我可能相信了错误的概念,即标准是一种没有错误的数学真理"——哦,绝对不是这样。听我这个贡献者说:标准只是一个纸质文件,用英文写成,并且不断变化(以至于每3年就会发布一版有重大改动的新版本)。编辑标准的人的目标是使其反映真实;但如果它已经反映了真实,就没有必要再进行编辑了。 :) - Quuxplusone
我可能曾经相信了一个错误的观念,即标准是一种没有错误的数学真理。哦,绝对不是这样的。听我这个贡献者说:标准只是一份纸质文件,用英语编写,不断变化(以至于每三年都会出版一份带有重大改动的新版本)。编辑标准的人的目标是使其反映真相;但如果它已经反映了真相,就没有理由再对其进行编辑了。 :) - undefined

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