gpt4 book ai didi

c++ - 将范围传递给 C++ 算法时如何处理 iterator/const_iterator 不匹配?

转载 作者:搜寻专家 更新时间:2023-10-31 00:01:53 25 4
gpt4 key购买 nike

我正在处理的项目的源代码的一部分,负责压缩一系列“事件”,如下所示:

#include <iterator>
#include <list>

typedef int Event;

typedef std::list<Event> EventList;

struct Compressor {
// Returns an iterator behind the last element which was 'eaten'
virtual EventList::const_iterator eatEvents( const EventList &l ) = 0;
};

// Plenty of Compressor subclasses exist

void compressAndCopyEatenEvents( Compressor &c ) {
EventList e;
e.push_back( 1 );
EventList::const_iterator newEnd = c.eatEvents( e );

EventList eatenEvents;
std::copy( e.begin(), newEnd, std::back_inserter( eatenEvents ) ); // barfs
}

这里的问题是 compressAndCopyEatenEvents 函数有一个非常量事件列表;此列表 os 传递给 eatEvents 方法,该方法采用对 const 的引用并产生 const_iterator。现在 compressAndCopyEatenEvenst 函数想要复制吃掉的事件范围,所以它决定使用一些算法(std::copy 这里,当然也可以替换为正确的 std::list 构造函数调用 - 关键是这个问题存在于各种范围)。

不幸的是(?)许多(如果不是全部?)范围需要由相同的迭代器类型组成。然而,在上面的代码中,'e.begin()' 产生一个 EventList::iterator(因为对象不是 const)但是 'newEnd' 是一个 EventList::const_iterator.

是否存在导致这种困惑的设计缺陷?你会如何解决?

最佳答案

在 C++03 中,唯一可能的方法是强制转换。 (这是丑陋的,这是一个设计缺陷,是的)。

std::copy( static_cast<EventList::const_iterator>e.begin(), newEnd, std::back_inserter( eatenEvents ) );

或者有另一个命名变量:

EventList::const_iterator constBegin = e.begin();
std::copy(constBegin , newEnd, std::back_inserter( eatenEvents ) );

在 C++11 中你有 cbegincend函数(总是返回 const_iterator s)所以你可以简单地做

std::copy( e.cbegin(), newEnd, std::back_inserter( eatenEvents ) );

关于c++ - 将范围传递给 C++ 算法时如何处理 iterator/const_iterator 不匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9094695/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com