如何实现一个公开多个范围的容器

How does one implement a container which exposes multiple ranges?

本文关键字:范围 何实现 实现 一个      更新时间:2023-10-16

我有一个容器,它(除其他外)公开了一个字符串缓冲区,以及该字符串缓冲区的大写版本。(好吧,这不仅仅是大写,但它在概念上是相似的)我想允许调用者做一些类似的事情:

container c("Example");
auto const iter = c.begin() + 2;
std::printf("%cn", iter->get_source()); // Prints a
std::printf("%cn", iter->get_upper()); // Prints A
iter->set('x');
std::puts(c.get()); // Prints Exxmple
std::puts(c.get_upper()); // Prints EXXMPLE

问题是,具有成员函数get_sourceget_upper等的"代理"类型没有明显的存储位置,并且需要迭代器来返回对某个对象的引用,而不是值。(vector<bool>也有类似的问题)

或者,我可以公开某种shell容器或范围,或者公开完全独立的迭代器开始/结束函数。有没有人有做这种事情的经验,知道什么效果好?

我个人处理这类事情的方法是使用属性映射:我设想了一个算法系统,它可以[可选]为每个范围获取一个属性映射(有时实际上是多个属性映射)。其思想是*it产生一个(例如,它当前所做的T&),然后与属性映射一起使用,属性映射将键转换为实际访问的。例如,转换可以是产生算法的当前行为的身份,以及在没有属性映射时使用的良好默认值。上面的例子看起来像这样:

auto const cursor = c.begin();
std::printf("%cn", c.map_source()(*cursor));
std::printf("%cn", c.map_upper()(*cursor));
c.map_source()(*cursor, 'x');
std::copy(c.map_source(), c, std::ostreambuf_iterator<char>(std::cout));
std::copy(c.map_upper(), c, std::ostreambuf_iterator<char>(std::cout));
std::copy([](unsigned char c)->char{ return std::toupper(c); }, c,
std::ostreambuf_iterator<char>(std::cout));

代码假设分别使用c.map_source()c.map_upper()获得产生源字符和大写字符的属性映射。使用std::copy()的最后一个变体使用lambda函数作为属性映射。

遗憾的是,我仍然没有时间写一份连贯的提案,对STL算法进行各种改进。。。我也没有一个将其整合在一起的实现(我有一个有点笨重的实现,它已经有10年的历史了,没有从各种C++11功能中受益,这些功能使它变得更容易;而且,这个实现只专注于属性映射,不使用我目前设想的接口)。