无法使BOOST_FOREACH与我的自定义类一起使用

拉米·阿尔·祖瓦里(Ramy Al Zuhouri)

我实现了一个普通的类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) {...}

这些是我得到的错误:

在此处输入图片说明

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

    通过引用返回将避免切片问题,但会引入更严重的问题:它返回对临时对象的引用¹。

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

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

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

  • 另外,根据页面的可扩展性,您似乎需要添加

    namespace boost {
        template<> struct range_mutable_iterator<MyClass> {
            typedef MyClass::MyIterator type;
        };
    
        template<> struct range_const_iterator<MyClass> {
            typedef MyClass::MyConstIterator type;
        };
    }
    
  • 对于您的迭代器类型,“三法则”实现存在严重麻烦(什么是“三法则”?)。

    每当迭代器不存在时,您都将删除容器的数据。而且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";
    }
}

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

需要帮助以获取自定义布局以与我的Android AlertDialog一起使用

<ReferenceArrayInput />不能与我的自定义数据提供程序一起使用(棱镜)

如何将 CMS 与我的自定义网站一起使用

我使用模板实现了队列以与我的自定义数据类型一起使用,但出现错误

使用bitronox管理器,XA无法与我的自定义dev-kit适配器一起使用

ssh可与我的自定义外壳一起使用,但不能直接使用ssh执行命令

将Boost图形库与顶点的自定义类一起使用

如何将 react-hook-form 与我自定义的 react-date-picker 一起使用?

:: boost :: tie为什么不能与BOOST_FOREACH一起使用?

我无法让我的ios自定义urlscheme与数字一起使用

NsArray ContainsObject无法与自定义NsObject类一起使用

自定义RewriteRule无法与WordPress一起使用?

我无法将自定义字体与Xamarin.Forms一起使用

为什么我的代码无法与自定义分配器一起使用?

将自定义类与自定义模板容器一起使用

我的自定义工具提示没有与我悬停的相应元素一起移动?

我想将Python Fabric与我的自定义运算符一起使用,如何在worker上安装Fabric?

如何将pd.apply与我自己的带有1个输入参数的自定义函数一起使用

为什么multiprocessing.Pool.map与我的自定义部分函数一起挂起?

HTML按钮无法与我的JavaScript一起使用

serialize()无法与我的表单一起使用

无法使SaveFileDialog与我的网页一起使用

ImageIcon无法与我一起使用

$ rootScope在AngularJs中无法与我一起使用

如何将boost :: assign与扩展STL容器的自定义容器一起使用?

C ++:如何使#define与自定义类一起使用?

如何使自定义类与 Python 中的“for in”循环一起使用?

iOS-将AFNetworking与自定义NSURLProtocol类一起使用

将 OpenGL VBO 与自定义类/数据结构一起使用