Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何实现公开多个范围的容器?_C++_Stl_Iterator - Fatal编程技术网

C++ 如何实现公开多个范围的容器?

C++ 如何实现公开多个范围的容器?,c++,stl,iterator,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->

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

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\u source
get\u upper
等的“proxy”类型没有明显的存储位置,需要迭代器返回对某个对象的引用,而不是值。(
vector
也有类似的问题)


或者,我可以公开某种shell容器或范围,或者公开完全独立的迭代器begin/end函数。有没有人有这样做的经验,并且知道什么工作效果很好?

我个人的做法是使用属性映射:一种算法,可以[可选地]为每个范围选择一个属性映射(有时实际上是多个属性映射)。其思想是,
*它
产生一个键(例如,
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));
auto const cursor=c.begin();
std::printf(“%c\n”,c.map_source()(*游标));
标准::printf(“%c\n”,c.map_upper()(*游标));
c、 map_source()(*光标,'x');
std::copy(c.map_source(),c,std::ostreambuf_迭代器(std::cout));
std::copy(c.map_upper(),c,std::ostreambuf_迭代器(std::cout));
std::copy([](unsigned char c)->char{return std::toupper(c);},c,
std::ostreambuf_迭代器(std::cout));
代码假设生成源和大写字符的属性映射分别使用
c.map\u source()
c.map\u upper()
获得。使用
std::copy()
的最后一个变量使用lambda函数作为属性映射


可悲的是,我还没有找到时间来写一个连贯的提案,对STL算法进行各种改进。。。我也没有一个完整的实现(我有一个大约有10年历史的实现,它没有从各种C++11特性中受益,这些特性使它变得更容易;而且,这个实现只关注属性映射,没有使用我目前设想的接口).

要求
运算符*
返回
T&
是针对前向迭代器的(C++11 24.2.5前向迭代器[前向迭代器]第1段)。对于输入或输出迭代器,它不适用。@Casey:在这种情况下,仅公开输入和/或输出迭代器是不够的--我想支持随机访问。看起来像是范围视图的工作在我的经验中,大多数只读算法在不返回引用的迭代器类对象上工作得很好。显然,排序不起作用。代理类型的习惯用法非常方便。问题是,这迫使人们放弃现有算法所需的大量工作,这些算法需要迭代器对或范围。标准委员会最终应用这一概念可能是一个有趣的概念,但从C++11/14及其标准库开始,我不认为这是一个惯用的解决方案。@BillyONeal:我当然同意这样的评估,即它不能很好地处理当前的算法。我正在讨论涉及到的各种变化(上面的代码使用范围和范围SG的属性映射),其中的想法通常很受欢迎;我只是说这并不能很好地回答今天的问题。