简体   繁体   English

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

[英]Override only operator*() of iterator of a custom datastructure

I have an array class MyArray with MyArray . 我有一个数组类MyArrayMyArray
For simplicity, this is the whole code. 为了简单起见,这就是整个代码。 It works OK. 可以。

Current code 当前代码

#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;
    }
};

Here is its usage :- 这是它的用法:

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

Problem / requirement 问题/要求

I have specific classes, let's say their names are B and C . 我有特定的类,可以说它们的名称是BC
I have a converter from B to C named convertBToC(B) . 我有一个BC 的转换器 ,名为convertBToC(B)

Now, I want a new datastructure (named MyArray2 ) that :- 现在,我想要一个新的数据结构(名为MyArray2 ):-

  • act mostly like MyArray<B> .... 表现得像MyArray<B> ...。
  • except that function operator*() of MyArray2 's iterator return C instead of B 除了MyArray2的迭代器的函数operator*() 返回C而不是B
  • the C that is returned, convert from B using convertBToC(B) . 返回的C ,使用convertBToC(B)B进行转换。

This is the usage that I wished for ( #1 ) :- 这是我希望用于( #1 )的用法:

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

The above code would work as if I call it like :- 上面的代码就像我这样称呼它:-

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

Question: How to code MyArray2 ? 问题:如何编写MyArray2

Criteria 标准

I want a solution that :- (sorted by priority) 我想要一个解决方案:-(按优先级排序)

  • efficient (not use std::function and its family) 高效(不使用std::function及其家族)
  • not refer to MyIterator directly (because MyIterator is an internal class) 不要直接引用MyIterator (因为MyIterator是一个内部类)
  • cute (low amounts of statement/line, readable) 可爱(语句/行少,可读)
  • minimum change to MyArray<T> (if any) MyArray<T>最小更改(如果有)

The most related question is here , but it mentions about std::vector . 最相关的问题在这里 ,但它提到了std::vector

My poor solutions 我可怜的解决方案

Solution 1 (2x inheritance) 解决方案1(2x继承)

Create 2 classes :- 创建2个课程:-

  • MyArray2 derived from MyArray<B> MyArray<B>派生的MyArray2
    Override: begin() or end() - return MyIterator2 . 覆盖: begin()end() -返回MyIterator2

  • MyIterator2 derived from MyIterator<B> MyIterator2衍生自MyIterator<B>
    Override: operator*() - return C (using convertBToC() ). 覆盖: operator*() -返回C (使用convertBToC() )。

Disadvantage: 坏处:

  • Dirty - I have to create 2 classes just to override only 1 function. 脏-我必须创建2个类才能仅覆盖1个函数。
  • MyArray2.h code contains the word MyIterator<T> . MyArray2.h代码包含单词MyIterator<T>

Solution 2 (lambda) 解决方案2(lambda)

Create only 1 class :- 仅创建1个课程:-

  • MyArray2 derived from MyArray<B> MyArray<B>派生的MyArray2
    new function: iterate() :- 新功能: iterate() :-

Here is the draft of iterate() :- 这是iterate()的草案:

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

The usage have to be changed from #1 to be ... ( #2 ) 用法必须从#1更改为...( #2

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

Disadvantage 坏处

  • It sometimes destroy readability. 有时会破坏可读性。 (Lambda sometimes harder to read) (Lambda有时更难阅读)
  • It limits coding style. 它限制了编码风格。 (Sometimes, I prefer range-based loop.) (有时,我更喜欢基于范围的循环。)

Another approach would be to use Boost range adaptors, specifically boost::adaptors::transformed . 另一种方法是使用Boost范围适配器,特别是boost::adaptors::transformed

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

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

Judge how much of an improvement it is yourself. 判断自己的进步有多大。 Maybe better put the operator| 也许最好把operator| call inside a new MyArray 's member function. 在新的MyArray的成员函数中调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM