如何实现暴露多个范围的容器?

Bil*_*eal 6 c++ iterator stl

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

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

std::puts(c.get()); // Prints Exxmple
std::puts(c.get_upper()); // Prints EXXMPLE
Run Code Online (Sandbox Code Playgroud)

问题是,"代理"类型的成员函数get_source,get_upper等没有明显的地方可以存放,而迭代器必须返回一个参考的东西,而不是一个值.(vector<bool>有类似的问题)

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

Die*_*ühl 1

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

auto const cursor = c.begin();
std::printf("%c\n", c.map_source()(*cursor));
std::printf("%c\n", 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));
Run Code Online (Sandbox Code Playgroud)

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

遗憾的是,我仍然没有时间写出一个连贯的提案来对 STL 算法应用各种改进。...我也没有一个将它们放在一起的实现(我有一个有点笨拙的实现,大约有 10 年历史,并且没有受益于各种 C++11 功能,这使得它变得更容易;而且,这个实现仅专注于属性映射,不使用我当前设想的界面)。