简体   繁体   English

std::set 使用 bitset 和共享静态数组专门用于 (u)int8 和字符是否合法

[英]Would it be legal for std::set to be specialized for (u)int8 and chars using bitset and shared static array

This is mostly a language lawyer kind of question, I doubt that most implementations would bother, especially since it would probably increase compile time for every user.这主要是一个语言律师类的问题,我怀疑大多数实现会打扰,特别是因为它可能会增加每个用户的编译时间。

That being said: If some implementation of std::set was implemented using bitset for each instance and static array of 256 values that is shared(it is safe since keys are const) would that be legal according to the (if edition matters then assume C++20) standard?话虽如此:如果 std::set 的某些实现是使用 bitset 为每个实例和共享的 256 个值的静态数组实现的(这是安全的,因为键是 const)根据(如果版本很重要,则假设)是合法的C++20) 标准?

I see no constraint that would forbid you to make a specialized implementation, as long as you respect the standard specifications in section [set] .我认为没有任何限制会禁止您进行专门的实现,只要您遵守[set]部分中的标准规范。

For set<char> or set<uint8_t> you'd need 32 octets to store the 256 bits representing the potential members, with the advantage of very fast set operations.对于set<char>set<uint8_t>您需要 32 个八位字节来存储表示潜在成员的 256 位,并具有非常快速的设置操作优势。 For set<int> you'd consume too much memory and this would only be justified IMHO if you'd have very populated sets.对于set<int>你会消耗太多内存,如果你有非常多的集合,这只会是合理的恕我直言。

This being said, there are some chalenges to overcome:话虽如此,仍有一些挑战需要克服:

  • you'd need to organize the array that maps values to bit positions, so that it is consistent with the provided comparator (cost at construction, unless you can share it)您需要组织将值映射到位位置的数组,以使其与提供的比较器一致(构建成本,除非您可以共享它)
  • you'll have to implement an iterator (but that's not really an issue, since the bitmap and a bit offset can do).你必须实现一个迭代器(但这并不是真正的问题,因为位图和位偏移量可以做到)。
  • since C++17 there is an exposed assumption that the data structure uses nodes since there is an extract() member that is supposed to return a value of the (unspecified) specialized type node_type .由于 C++17 有一个公开的假设,即数据结构使用节点,因为有一个extract()成员应该返回(未指定的)专用类型node_type Not sure what this requirement implies, but I think it could be solved in a similar manner than the iterator issue above.不确定这个要求意味着什么,但我认为它可以通过与上面的迭代器问题类似的方式来解决。
  • You'd need to comply with the complexity requirements (see NathanOlivier's comment to your question).您需要遵守复杂性要求(请参阅 NathanOlivier 对您的问题的评论)。 The difficulty comes from the ordering of the shared array.困难来自共享数组的排序。 However, if you'd use two shared arrays (one to convert value into bit-offset, and one to convert bit-offset into value), or one array of pairs, you could insert anything in O(1).但是,如果您使用两个共享数组(一个将值转换为位偏移量,一个将位偏移量转换为值)或一组对,则可以在 O(1) 中插入任何内容。

EDIT: Made a mistake.编辑:犯了一个错误。 Proxy iterators are not allowed in C++17. C++17 中不允许使用代理迭代器。

I think it is not possible.我认为这是不可能的。 First: That implementation will hold all complexity guarantees and will for most of them be better than the requirements.第一:该实现将拥有所有复杂性保证,并且对于大多数复杂性保证而言,将比要求更好。

Second: You are not allowed to create proxy-iterator when using standard container since they had to return real references at some points.第二:使用标准容器时不允许创建代理迭代器,因为它们必须在某些时候返回真实引用。 (The std::bitset mentioned by @Christophe is not a container and has a proxy-reference in its definition. The std::vector < bool > is a famous example for breaking guarantees.). (@Christophe 提到的 std::bitset 不是容器,并且在其定义中具有代理引用。std::vector < bool > 是破坏保证的著名示例。)。 So it is not possible to use that implementation.所以不可能使用该实现。

Edit: Tanks to @NicolBolas for pointing that proxy iterators are still not allowed.编辑:坦克到@NicolBolas 指出仍然不允许使用代理迭代器。

Cristophe's answer contains an important point:克里斯托夫的回答包含一个重要的观点:

  • you'd need to organize the array that maps values to bit positions, so that it is consistent with the provided comparator (cost at construction, unless you can share it)您需要组织将值映射到位位置的数组,以使其与提供的比较器一致(构建成本,除非您可以共享它)

This points to a challenging problem of dealing with stateful comparators (when the ordering relation is not a fixed one, but can be controlled from the outside and dynamically changed at run-time).这指向处理有状态比较器的一个具有挑战性的问题(当排序关系不是固定的,但可以从外部控制并在运行时动态更改时)。 Although frowned upon by the general C++ folks, I couldn't find anything in the standard that prohibits stateful comparators for associative containers (but I didn't look too hard).虽然不赞成由一般C ++的乡亲,我找不到在禁止状态比较关联容器标准的任何东西(但我没有看太用力)。 If you manage the state of the comparator and the content of the set so that the ordering requirement is never violated, then it works in practice (at least, it has worked for me).如果您管理比较器的状态和集合的内容,以便永远不会违反排序要求,那么它在实践中起作用(至少,它对我有用)。

So my verdict is that in the most general case of an arbitrary comparator std::set cannot be specialized for small integral types using a bitset and any supporting shared static data.所以我的结论是,在任意比较器std::set的最一般情况下,不能专门用于使用bitset和任何支持共享静态数据的小型整数类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM