Override only operator*() of iterator of a custom datastructure

javaLover

I have an array class MyArray with MyArray.
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.
I have a converter from B to C named convertBToC(B).

Now, I want a new datastructure (named MyArray2) that :-

  • act mostly like MyArray<B> ....
  • except that function operator*() of MyArray2's iterator return C instead of B
  • the C that is returned, convert from B using convertBToC(B).

This is the usage that I wished for (#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?

Criteria

I want a solution that :- (sorted by priority)

  • efficient (not use std::function and its family)
  • not refer to MyIterator directly (because MyIterator is an internal class)
  • cute (low amounts of statement/line, readable)
  • minimum change to MyArray<T> (if any)

The most related question is here, but it mentions about std::vector.

My poor solutions

Solution 1 (2x inheritance)

Create 2 classes :-

  • MyArray2 derived from MyArray<B>
    Override: begin() or end() - return MyIterator2.

  • MyIterator2 derived from MyIterator<B>
    Override: operator*() - return C (using convertBToC()).

Disadvantage:

  • Dirty - I have to create 2 classes just to override only 1 function.
  • MyArray2.h code contains the word MyIterator<T>.

Solution 2 (lambda)

Create only 1 class :-

  • MyArray2 derived from MyArray<B>
    new function: iterate() :-

Here is the draft of 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)

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

Disadvantage

  • It sometimes destroy readability. (Lambda sometimes harder to read)
  • It limits coding style. (Sometimes, I prefer range-based loop.)
LogicStuff

Another approach would be to use Boost range adaptors, specifically 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| call inside a new MyArray's member function.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Overloaded `!=` operator in custom iterator class is not working properly

From Dev

Error with iterator relation operator (Custom HashTable w/ Separate Chaining and Iterators)

From Dev

Override iterator type

From Dev

How to use networkx algorithm with my custom graph datastructure?

From Dev

Iterator and Increment operator

From Dev

Why does my custom iterator require a call operator in range based for loops?

From Dev

Custom Iterator using boost iterator

From Dev

How to override = operator in Scala

From Dev

Override binary << operator on struct

From Dev

Null coalescing operator override

From Dev

How to override `is` operator

From Dev

Null coalescing operator override

From Dev

Override binary << operator on struct

From Dev

Performance difference with custom iterator

From Dev

Creating custom Iterator Java?

From Java

operator-> for an iterator that returns a temporary

From Dev

arrow operator and boost multiarray iterator

From Dev

MSVC 2015 - compiler error in std::for_each for custom iterator (only when in DEBUG)

From Dev

Override operator of built-in object

From Dev

Override istream operator >> and modify delimiter

From Dev

Is it possible to override the assignment ('=') operator in Python?

From Dev

override operator invalid in c++

From Dev

Override operator of built-in object

From Dev

How to override operator+ in subclass

From Dev

Override jQuery custom event

From Dev

Override a custom function value

From Dev

Override a custom function value

From Dev

override a custom validation

From Dev

custom iterator which can traverse iterator