我有一个容器,其中(除其他外)暴露了一个字符串缓冲区,以及该字符串缓冲区的大写版本。 (好吧,它不只是大写,但它在概念上类似)我想允许调用者做类似的事情:
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_source
,get_upper
等的“代理”类型没有可以存储的明显位置,并且需要迭代器来返回对某些内容的引用,而不是价值。 (vector<bool>
有类似的问题)
或者我可以暴露某种shell容器或范围,或者暴露完全独立的迭代器开始/结束函数。有没有人有经验做这样的事情,知道什么效果很好?
答案 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函数作为属性映射。