flat_map是 STL 容器吗?

Is flat_map an STL container?

提问人:tommsch 提问时间:11/13/2022 最后编辑:Nicol Bolastommsch 更新时间:6/16/2023 访问量:591

问:

在当前的 C++23s 设计草案中,类型被定义为 ,即它不是对 的引用。 (这似乎是强制性的,因为键和值不是成对存储的,而是存储在两个单独的容器中。 因此,迭代器必须是某个代理类。flat_mapflat_map::referencepair<const key_type&, mapped_type&>flat_map::value_type = pair<key_type, mapped_type>

这让我想到:一个实际上是一个 STL 容器,类似于 is 不是一个?flat_mapstd::vector<bool>

C++ STL 容器 C++23

评论

0赞 Jesper Juhl 11/13/2022
“STL”是一个非常古老的库(标准模板库),被合并到C++98标准库中。STL的标准部分是否添加了任何后续内容?不。它是标准库的一部分吗,是的。
0赞 FrankHB 1/24/2023
@JesperJuhl 这在历史意义上是正确的,但现在它变得更加模糊。在 WG21 讨论的上下文中,“STL”可能表示 Stephan T. Lavavej,他是 microsoft/STL 的维护者。后者当前ISO C++标准库的最新实现,IIRC STL先生强烈坚持使用该名称。

答:

3赞 Nicol Bolas 11/13/2022 #1

该标准定义了 [container.reqmts] 中的“容器”是什么。这些要求包括

typename X::reference

  • 结果:T&

所以是的,不是容器。std::flat_map

但它从不声称是;它是一个“容器适配器”

A是容器适配器...flat_­map

请注意,像 一样,将容器类型作为模板参数。std::stack/queue/priority_queuestd::flat_set/map

还应该注意的是,虽然它们不是容器,但它们是由 C++20 范围库的概念定义的范围。C++20 范围概念允许引用类型不必是 value_type&.

评论

1赞 HarryLeong 3/1/2023
该标准说“flat_map满足容器的所有要求。但这并不完全准确,是吗?我对标准中的这一说法感到有点不确定。
1赞 Quuxplusone 6/16/2023 #2

作者 P2767R0 这里.这都是迂腐的,有多少天使可以在针头上跳舞,所以虽然我要提出我自己的迂腐答案,但请理解,我并不是说其他人的不同答案一定是错误的。这在实践中同样无关紧要

(1)本身(类模板)不是一个容器;它是一个容器适配器。甚至不是容器;它是用于冲压容器的模板。在我的世界观中,“容器适配器”是用于消除容器的模板,其中一个模板参数本身就是一个容器。比较“迭代器适配器”(和“范围”中的“视图适配器”)的用法。“类模板reverse_iterator是一个迭代器适配器”,但类型的对象(简单地)是一个迭代器。 是容器适配器;类型的对象(简单地说)是一个容器。flat_mapvectorreverse_iterator<int*>flat_setflat_set<int>

请注意,[vector.overview] 没有说“类模板是一个序列容器...”;它说“A 是一个序列容器......”也就是说,某种特殊化的对象(简单地)是一个容器。vectorvectorvector

“但是 [sequences.general] 说,'标头<array>、<deque>、<forward_list>、<list> 和 <vector> 定义了满足序列容器要求的类模板!'你如何与你声称类模板不是容器的说法相符?

好吧,你肯定同意没有定义任何满足序列容器要求的类模板,对吧?我们可以争论,但绝对不是一个容器。所以这句话从表面上看是错误的。<array>vector<bool>array

(同时,TIL 表示 C++23 的 [vector.bool]/8 意味着允许用户为 提供“程序定义的专业化”。谁知道这样的专业化会做什么!vector<bool, A>

(2) As far as I'm concerned, is a container. As you observed, [flat.map]/2 says explicitly that "meets all of the requirements of a container." Sure, on one hand it seems clearly to fail the requirement... but on the other hand, the standard says it meets all the requirements! Something's got to give; and I think it makes vastly more sense to assume that the C++98-era [container.reqmts] is out of sync with C++23's reality, than to assume that the C++23-era [flat.map] is out of sync. Someone just needs to update [container.reqmts] to handle the modern possibility of proxy reference types.flat_map<int, int>flat_mapX::reference

评论

0赞 tommsch 7/4/2023
Someone just needs to update [container.reqmts] ... Thats a good point, but it also implies that we cannot really rely on the C++ standard. What's a container, meeting all the container requirements, worth then? I may believed in the wrong concept that the standard is some kind of mathematical truth without errors (Which actually would make sense, since C++ is a language for deterministic computers).
0赞 Quuxplusone 7/5/2023
"I may [have] believed in the wrong concept that the standard is some kind of mathematical truth without errors" — Oh yeah, absolutely not. Take it from a contributor: the Standard is just a paper document, written in English, that changes constantly (such that a new edition with major changes comes out every 3 years). Those who edit it have the goal of making it reflect the truth; but if it already did reflect the truth, there'd be no reason to edit it any more. :)