如何在与C+中的派生类型匹配的元素上创建迭代器+;? 我希望C++中的迭代器只能对特定类型的元素进行迭代。在下面的示例中,我只想迭代属于子类型实例的元素 vector<Type*> the_vector; the_vector.push_back(new Type(1)); the_vector.push_back(new SubType(2)); //SubType derives from Type the_vector.push_back(new Type(3)); the_vector.push_back(new SubType(4)); vector<Type*>::iterator the_iterator; //***This line needs to change*** the_iterator = the_vector.begin(); while( the_iterator != the_vector.end() ) { SubType* item = (SubType*)*the_iterator; //only SubType(2) and SubType(4) should be in this loop. ++the_iterator; } vector\u向量; 推回向量(新类型(1)); _向量。推回(新的子类型(2))//子类型派生自类型 推回向量(新类型(3)); _向量。推回(新的子类型(4)); 向量::迭代器-迭代器//***这条线路需要改变*** _迭代器=_向量.begin(); while(迭代器!=向量.end()){ 子类型*项=(子类型*)*迭代器; //此循环中只应包含子类型(2)和子类型(4)。 ++迭代器; } < P> >如何在C++中创建这个迭代器?< P>如PruttBaulbb在评论中所说,应该创建自己的迭代器类,也许继承自 vector::迭代器< /> >。特别是,您需要实现或覆盖operator++()和operator++(int)以确保跳过非子类型对象(您可以使用dynamic_cast()检查每个项)。在这个O'Reilly网络中,有一个很好的关于实现您自己的容器和迭代器的概述。
您必须使用动态强制转换如何在与C+中的派生类型匹配的元素上创建迭代器+;? 我希望C++中的迭代器只能对特定类型的元素进行迭代。在下面的示例中,我只想迭代属于子类型实例的元素 vector<Type*> the_vector; the_vector.push_back(new Type(1)); the_vector.push_back(new SubType(2)); //SubType derives from Type the_vector.push_back(new Type(3)); the_vector.push_back(new SubType(4)); vector<Type*>::iterator the_iterator; //***This line needs to change*** the_iterator = the_vector.begin(); while( the_iterator != the_vector.end() ) { SubType* item = (SubType*)*the_iterator; //only SubType(2) and SubType(4) should be in this loop. ++the_iterator; } vector\u向量; 推回向量(新类型(1)); _向量。推回(新的子类型(2))//子类型派生自类型 推回向量(新类型(3)); _向量。推回(新的子类型(4)); 向量::迭代器-迭代器//***这条线路需要改变*** _迭代器=_向量.begin(); while(迭代器!=向量.end()){ 子类型*项=(子类型*)*迭代器; //此循环中只应包含子类型(2)和子类型(4)。 ++迭代器; } < P> >如何在C++中创建这个迭代器?< P>如PruttBaulbb在评论中所说,应该创建自己的迭代器类,也许继承自 vector::迭代器< /> >。特别是,您需要实现或覆盖operator++()和operator++(int)以确保跳过非子类型对象(您可以使用dynamic_cast()检查每个项)。在这个O'Reilly网络中,有一个很好的关于实现您自己的容器和迭代器的概述。,c++,stl,iterator,C++,Stl,Iterator,您必须使用动态强制转换 the_iterator = the_vector.begin(); while( the_iterator != the_vector.end() ) { SubType* item = dynamic_cast<SubType*>(*the_iterator); if( item != 0 ) ... //only SubType(2) and SubType(4) should be in this loop.
the_iterator = the_vector.begin();
while( the_iterator != the_vector.end() ) {
SubType* item = dynamic_cast<SubType*>(*the_iterator);
if( item != 0 )
...
//only SubType(2) and SubType(4) should be in this loop.
++the_iterator;
}
the_iterator=the_vector.begin();
while(迭代器!=向量.end()){
子类型*item=dynamic\u cast(*迭代器);
如果(项目!=0)
...
//此循环中只应包含子类型(2)和子类型(4)。
++迭代器;
}
无增压的解决方案。但是,如果您可以访问boost库,请按照建议使用过滤器迭代器
template <typename TCollection, typename T>
class Iterator
{
public:
typedef typename TCollection::iterator iterator;
typedef typename TCollection::value_type value_type;
Iterator(const TCollection& collection,
iterator it):
collection_(collection),
it_(it)
{
moveToNextAppropriatePosition(it_);
}
bool operator != ( const Iterator& rhs )
{
return rhs.it_ != it_;
}
Iterator& operator++()
{
++it_;
moveToNextAppropriatePosition(it_);
return *this;
}
Iterator& operator++(int);
Iterator& operator--();
Iterator& operator--(int);
value_type& operator*()
{
return *it_;
}
value_type* operator->()
{
return &it_;
}
private:
const TCollection& collection_;
iterator it_;
void moveToNextAppropriatePosition(iterator& it)
{
while ( dynamic_cast<T*>(*it) == NULL && it != collection_.end() )
++it;
}
};
class A
{
public:
A(){}
virtual ~A(){}
virtual void action()
{
std::cout << "A";
}
};
class B: public A
{
public:
virtual void action()
{
std::cout << "B";
}
};
int main()
{
typedef std::vector< A* > Collection;
Collection c;
c.push_back( new A );
c.push_back( new B );
c.push_back( new A );
typedef Iterator<Collection, B> CollectionIterator;
CollectionIterator begin(c, c.begin());
CollectionIterator end(c, c.end());
std::for_each( begin, end, std::mem_fun(&A::action) );
}
模板
类迭代器
{
公众:
typedef typename TCollection::迭代器迭代器;
typedef typename TCollection::value_type value_type;
迭代器(const t收集和收集,
迭代器(it):
收集(收集),,
it(it)
{
移动到下一个适当的位置(it_);
}
布尔运算符!=(常量迭代器和rhs)
{
返回rhs.it!=it;
}
迭代器和运算符++()
{
++它!;
移动到下一个适当的位置(it_);
归还*这个;
}
迭代器和运算符++(int);
迭代器和运算符——();
迭代器和运算符--(int);
值类型和运算符*()
{
返回*它u;
}
值类型*运算符->()
{
返回&it;
}
私人:
const t收集和收集;
迭代器;
void movetonextpropertiposition(迭代器&it)
{
while(dynamic_cast(*it)=NULL&&it!=collection_u.end())
++它;
}
};
甲级
{
公众:
A(){}
虚拟~A(){}
虚拟无效操作()
{
std::cout只是使用boost迭代器的另一种方法。这一次,使用std::remove\u copy\u if
:
std::remove_copy_if(v.begin(), v.end(),
boost::make_function_output_iterator(boost::bind(&someFunction, _1)),
!boost::lambda::ll_dynamic_cast<SubType*>(boost::lambda::_1));
std::如果(v.begin(),v.end(),则删除副本,
boost::make_function_output_迭代器(boost::bind(&someFunction,_1)),
!boost::lambda::ll_dynamic_cast(boost::lambda::_1));
它将为指向子类型的每个指针调用一个函数(在本例中为someFunction
。但它可以是boost::bind可以构造的任何东西-也是一个成员函数)难道不可能创建自己的迭代器(或子类)吗这将跳过除子类型对象以外的任何内容?很好的答案,我也想这么做:)如果有一个小例子会更好。我会建议BOOST_FOREACH(Type*t,make_pair(make_filter_iterator)(ll_dynamic_cast(_1),v.begin(),v.end()),make_filter_iterator(ll_dynamic_cast(_1),v.end(),v.end()){…}(使用boost.iterators、boost.lambda和boost.foreach)太好了!我觉得应该有现成的解决方案。谢谢。永远不知道还有什么boost。您必须小心不要将迭代器的增量超过容器的末尾。为此,您将需要包装器保留“end”迭代器的副本,这样您将有一个停止条件。或者只使用boost::filter_迭代器作为Sanjaya su这是问题中“检查正确的子类型”部分的解决方案,但它有一个缺陷,在到达最后一个子类型元素后,它将继续增加迭代器,使其超出容器的末尾。dribeas,我不知道这怎么可能发生。他在循环的头部得到了正确的条件。原始问题on甚至没有提到动态强制转换,所以我认为海报不知道动态强制转换,并且在错误的方向上寻找解决方案(更改与迭代器相关的内容)。在建议解决方案之前(构建自己的迭代器)这可能比必要的复杂得多,我更倾向于首先提出解决原始问题的最简单方法。然后,正如我的省略号和缩进所暗示的,迭代器当然不能位于if(item!=0)块中。