仅覆盖自定义数据结构的迭代器的operator *()

时间:2017-02-19 10:29:10

标签: c++ c++11 data-structures iterator

我有一个MyArray的数组MyArray 为简单起见,这是整个代码。它运作正常。

当前代码

#include <iostream>
using namespace std;
template<class T> class MyArray;
template<class T>class MyIterator{
    public: int index=0;
    public: MyArray<T>* myArray;
    public: MyIterator<T> operator++(){
        index++;
        return *this;
    }
    public: T& operator*(){
        return myArray->database[index];
    }
    public: friend bool operator!=(MyIterator<T> b,MyIterator<T> c){
        return b.index!=c.index;
    }
};
template<class T>class MyArray{
    public: T database[5];
    public: MyArray(){
        database[2]=3; //just fill with something to test
    }
    public: MyIterator<T> begin(){
        MyIterator<T> r;  r.index=0; r.myArray=this;
        return r;
    }
    public: MyIterator<T> end(){
        MyIterator<T> r;  r.index=5; r.myArray=this;
        return r;
    }
};

以下是它的用法: -

int main() {
    MyArray<int> test;
    for(int ele:test){
        std::cout<<ele<<std::endl;
    }
    return 0;
}

问题/要求

我有特定的类,假设他们的名字是BC
我从名为B的{​​{1}}到C 转换器

现在,我想要一个新的数据结构(名为convertBToC(B)): -

  • 主要表现为MyArray2 ....
  • 除了MyArray<B>的迭代器返回operator*()而不是MyArray2
  • 的函数C
  • 返回的B,使用CB转换。

这是我希望的用法(convertBToC(B)): -

#1

上面的代码就好像我称之为: -

MyArray2 test;
//test.push_back(B());  //used like "MyArray<B>"
for(C c:test){          //"C", not "B"
    .... logic about "c" ....  
}  

问题:如何编码MyArray<B> arr; for(B& b: arr){ C c= convertBToC(b); //<-- I want to hide this line .... logic about "c" .... }

标准

我想要一个解决方案: - (按优先级排序)

  • 高效(不使用MyArray2及其家人)
  • 不直接引用std::function(因为MyIterator是内部类)
  • 可爱(声明/线条数量少,可读)
  • 最小更改为MyIterator(如果有)

最相关的问题是here,但它提到了MyArray<T>

我糟糕的解决方案

解决方案1(2x继承)

创建2个类: -

  • std::vector派生自MyArray2
    覆盖: MyArray<B>begin() - 返回end()

  • MyIterator2派生自MyIterator2
    覆盖: MyIterator<B> - 返回operator*()(使用C)。

缺点:

  • 脏 - 我必须只创建2个类才能覆盖1个函数。
  • convertBToC()代码包含单词MyArray2.h

溶液2(λ)

只创建一个类: -

  • MyIterator<T>派生自MyArray2
    新功能: MyArray<B>: -

以下是iterate()草稿: -

iterate()

必须将使用情况从template<typename F> MyArray2::iterate( F lamdbaFunction ){ for(B b: MyArray<B>){ C c= convertBToC(b); lamdbaFunction(c); } } 更改为...(#1

#2

缺点

  • 有时会破坏可读性。 (Lambda有时难以阅读)
  • 它限制了编码风格。 (有时,我更喜欢基于范围的循环。)

1 个答案:

答案 0 :(得分:2)

另一种方法是使用Boost范围适配器,特别是boost::adaptors::transformed

#include <boost/range/adaptor/transformed.hpp>
...

MyArray<B> test;
for(C ele : test | boost::adaptor::transformed(convertBToC)) {
    // something...
}

判断自己有多大改进。也许最好将operator|调用放在新的MyArray成员函数中。