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

时间:2013-12-22 02:17:37

标签: c++ stl iterator

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

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

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

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

1 个答案:

答案 0 :(得分:1)

我对此类事物的个人处理方法是使用属性映射:我envision a system算法可以[可选]获取属性映射(实际上有时是多个属性映射)每个范围。我们的想法是*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));

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

遗憾的是,我还没有时间写出一个连贯的提案来对STL算法进行各种改进。 ...我也没有一个实现将它们放在一起(我有一个大约10年的somewhat clunky implementation并且没有受益于各种C ++ 11功能,这使得它更容易;而且,这个实现只关注属性映射,不使用我当前设想的接口。