我有一个数组类 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;
}
问题/需求
我有特定类,假设他们的名字是B
和 C
.
我有来自 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/