我有一个数组类MyArrayMyArray
为了简单起见,这就是整个代码。可以。

当前代码

#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
我有一个从BC的转换器,名为convertBToC(B)

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


表现得像MyArray<B> ....
除了operator*()的迭代器的函数MyArray2返回C而不是B
返回的C,使用BconvertBToC(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是内部类)
可爱(语句/行少,可读)
MyArray<T>的最小更改(如果有)


最相关的问题是here,但它提到了std::vector

我可怜的解决方案

解决方案1(2x继承)

创建2个课程:-


源自MyArray2MyArray<B>
覆盖:begin()end()-返回MyIterator2
源自MyIterator2MyIterator<B>
覆盖:operator*()-返回C(使用convertBToC())。


坏处:


脏-我必须创建2个类才能仅覆盖1个函数。
MyArray2.h代码包含单词MyIterator<T>


解决方案2(lambda)

仅创建1个课程:-


源自MyArray2MyArray<B>
新功能:iterate():-


这是iterate()的草稿:-

template<typename F> MyArray2::iterate( F lamdbaFunction ){
    for(B b: MyArray<B>){
         C c= convertBToC(b);
         lamdbaFunction(c);
    }
}


用法必须从#1更改为...(#2

MyArray2 arr;
auto lambdaF=[&](C c){
    .... logic about "c" ....
}
arr.iterateElement(lambdaF);


坏处


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

最佳答案

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

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

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


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

关于c++ - 覆盖自定义数据结构的迭代器的仅运算符*(),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42326130/

10-11 21:04