gpt4 book ai didi

c++ - 无法让 BOOST_FOREACH 与我的自定义类一起工作

转载 作者:行者123 更新时间:2023-11-30 02:41:56 25 4
gpt4 key购买 nike

我实现了一个简单的类 MyClass,其中有一个分配有 new 的数组(我知道我可以使用 STL 容器,但我试图理解他们是如何工作的)。我还创建了一个迭代器子类,能够迭代 MyClass 对象的所有元素:

class MyIterator : public iterator<forward_iterator_tag,int>
{
private:
int* data= nullptr;
int length;
int pointer=0;
int nullvalue=0;
public:
MyIterator(int* data, int length, bool end= false)
{
this->data= data;
this->length= length;
if(end)
pointer=-1;
}
~MyIterator()
{
delete[] data;
}
MyIterator& operator++()
{
if(pointer!= length-1)
{
pointer++;
}
else
{
pointer= -1;
}
return *this;
}
bool operator==(const MyIterator& other)
{
return pointer==other.pointer;
}
bool operator!=(const MyIterator& other)
{
return pointer!= other.pointer;
}
int& operator* ()
{
if(pointer==-1)
return nullvalue;
else
return data[pointer];
}
};

class MyClass
{
private:
int* data= nullptr;
int length= 100;
public:
MyClass()
{
data= new int[length];
for(int i=0; i<length;i++)
data[i]=i+1;
}
iterator<forward_iterator_tag,int> begin()
{
return MyIterator(data,length);
}
iterator<forward_iterator_tag,int> end()
{
return MyIterator(data,length,true);
}
};

如果我这样使用迭代器,它会工作:

for(MyIterator i= MyClass_instance.begin(); i!=MyClass_instance.end();i++) {...}

如果我尝试将它与 BOOST_FOREACH 一起使用,它不起作用:

BOOST_FOREACH(int i, MyClass_instance) {...}

这些是我得到的错误:

enter image description here

最佳答案

  • 您通过将迭代器作为 std::iterator<> 返回来对迭代器进行切片。 按值。你不能那样做。

    通过引用返回可以避免切片问题但是引入了一个更糟糕的问题:它返回对临时对象¹的引用。

    因此,通过按值返回您的实际迭代器类型来修复它。

  • 您的类型缺少 const 迭代器。

  • 所有迭代器成员都不是常量正确的。

  • 另外,根据页面 Extensibility 看来你需要添加

    namespace boost {
    template<> struct range_mutable_iterator<MyClass> {
    typedef MyClass::MyIterator type;
    };

    template<> struct range_const_iterator<MyClass> {
    typedef MyClass::MyConstIterator type;
    };
    }
  • 您的迭代器类型 (What is The Rule of Three?) 的三规则实现存在严重问题。

    每次迭代器消失时,您都在删除容器的数据。和 MyClass本身从不释放数据...

修复以上大部分(?):

Live On Coliru

#include <iterator>
#include <boost/foreach.hpp>

class MyClass
{
private:
int* data = nullptr;
int length = 100;

public:
class MyIterator : public std::iterator<std::forward_iterator_tag, int>
{
public:
MyIterator(int* data, int length, bool end = false)
{
this->data= data;
this->length= length;
if(end)
pointer=-1;
}
MyIterator& operator++()
{
if(pointer!= length-1) {
pointer++;
}
else {
pointer= -1;
}
return *this;
}

bool operator==(const MyIterator& other) const { return pointer==other.pointer; }
bool operator!=(const MyIterator& other) const { return pointer!= other.pointer; }
int& operator*() const
{
if(pointer==-1)
return nullvalue;
else
return data[pointer];
}
private:
value_type* data = nullptr;
int length;
int pointer = 0;
mutable value_type nullvalue = 0;
};

class MyConstIterator : public std::iterator<std::forward_iterator_tag, const int>
{
public:
MyConstIterator(int const* data, int length, bool end = false)
{
this->data= data;
this->length= length;
if(end)
pointer=-1;
}
MyConstIterator& operator++()
{
if(pointer!= length-1) {
pointer++;
}
else {
pointer= -1;
}
return *this;
}

bool operator==(const MyConstIterator& other) const { return pointer==other.pointer; }
bool operator!=(const MyConstIterator& other) const { return pointer!= other.pointer; }
int const& operator*() const
{
if(pointer==-1)
return nullvalue;
else
return data[pointer];
}
private:
value_type* data = nullptr;
int length;
int pointer = 0;
value_type nullvalue = 0;
};

public:
typedef MyIterator iterator_type;
typedef MyConstIterator const_iterator_type;

MyClass()
{
data= new int[length];
for(int i=0; i<length;i++)
data[i]=i+1;
}
~MyClass() {
delete[] data;
}
iterator_type begin() { return MyIterator(data,length); }
iterator_type end() { return MyIterator(data,length,true); }
const_iterator_type begin() const { return MyConstIterator(data,length); }
const_iterator_type end() const { return MyConstIterator(data,length,true); }
};

namespace boost {
template<> struct range_mutable_iterator<MyClass> {
typedef MyClass::MyIterator type;
};

template<> struct range_const_iterator<MyClass> {
typedef MyClass::MyConstIterator type;
};
}

#include <iostream>

int main()
{
MyClass c;
BOOST_FOREACH(int i, c) {
std::cout << i << "\n";
}
}

¹(除非您将迭代器存储在其他地方,但出于许多原因,这将是一个巨大的反模式)

关于c++ - 无法让 BOOST_FOREACH 与我的自定义类一起工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27593149/

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