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

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

我有一个数组类 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 .
我有来自 B转换器C名为 convertBToC(B) .

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

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

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

我糟糕的解决方案

解决方案 1(2 倍继承)

创建 2 个类:-

  • MyArray2源自 MyArray<B>
    覆盖: begin()end() - 返回 MyIterator2 .

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

缺点:

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

解决方案 2(lambda)

只创建 1 个类:-

  • 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)

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++ - 仅覆盖自定义数据结构的迭代器的 operator*(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42326130/

相关文章:

c++ - 在 C++ 中对排序数组进行 bin 的有效方法

c++ - GCC "Internal compiler error: Error reporting routines re-entered"(包含完整代码)

java - 理解Java中的类变量

java - Java 6接口(interface)MultivaluedMap有什么用?

c++ - 命令行 XRandR 和自己的代码之间的差异

C++使用谓词在元组列表中查找元素

c++ - 正确使用右值引用作为参数

c++ - 将军树高度

c++ - QProcess 多平台命令

c++ - 在m文件中包含mm文件