Nun, heute suchte ich auch nach einer einfachen Implementierung der Sammlung unter C ++ 11. Eigentlich war ich enttäuscht, weil alles, was ich gefunden habe, zu weit von Dingen wie Python-Generatoren oder C # -Ertragsoperatoren entfernt ist ... oder zu kompliziert.
Der Zweck besteht darin, eine Sammlung zu erstellen, die ihre Gegenstände nur dann ausgibt, wenn dies erforderlich ist.
Ich wollte, dass es so ist:
auto emitter = on_range<int>(a, b).yield(
[](int i) {
/* do something with i */
return i * 2;
});
Ich fand diesen Beitrag, IMHO beste Antwort war über boost.coroutine2, von Yongwei Wu . Da es dem Autor am nächsten kommt.
Es lohnt sich, Boost Couroutinen zu lernen. Und ich werde es vielleicht am Wochenende tun. Bisher verwende ich jedoch meine sehr kleine Implementierung. Hoffe es hilft jemand anderem.
Unten finden Sie ein Beispiel für die Verwendung und anschließende Implementierung.
Example.cpp
#include <iostream>
#include "Generator.h"
int main() {
typedef std::pair<int, int> res_t;
auto emitter = Generator<res_t, int>::on_range(0, 3)
.yield([](int i) {
return std::make_pair(i, i * i);
});
for (auto kv : emitter) {
std::cout << kv.first << "^2 = " << kv.second << std::endl;
}
return 0;
}
Generator.h
template<typename ResTy, typename IndexTy>
struct yield_function{
typedef std::function<ResTy(IndexTy)> type;
};
template<typename ResTy, typename IndexTy>
class YieldConstIterator {
public:
typedef IndexTy index_t;
typedef ResTy res_t;
typedef typename yield_function<res_t, index_t>::type yield_function_t;
typedef YieldConstIterator<ResTy, IndexTy> mytype_t;
typedef ResTy value_type;
YieldConstIterator(index_t index, yield_function_t yieldFunction) :
mIndex(index),
mYieldFunction(yieldFunction) {}
mytype_t &operator++() {
++mIndex;
return *this;
}
const value_type operator*() const {
return mYieldFunction(mIndex);
}
bool operator!=(const mytype_t &r) const {
return mIndex != r.mIndex;
}
protected:
index_t mIndex;
yield_function_t mYieldFunction;
};
template<typename ResTy, typename IndexTy>
class YieldIterator : public YieldConstIterator<ResTy, IndexTy> {
public:
typedef YieldConstIterator<ResTy, IndexTy> parent_t;
typedef IndexTy index_t;
typedef ResTy res_t;
typedef typename yield_function<res_t, index_t>::type yield_function_t;
typedef ResTy value_type;
YieldIterator(index_t index, yield_function_t yieldFunction) :
parent_t(index, yieldFunction) {}
value_type operator*() {
return parent_t::mYieldFunction(parent_t::mIndex);
}
};
template<typename IndexTy>
struct Range {
public:
typedef IndexTy index_t;
typedef Range<IndexTy> mytype_t;
index_t begin;
index_t end;
};
template<typename ResTy, typename IndexTy>
class GeneratorCollection {
public:
typedef Range<IndexTy> range_t;
typedef IndexTy index_t;
typedef ResTy res_t;
typedef typename yield_function<res_t, index_t>::type yield_function_t;
typedef YieldIterator<ResTy, IndexTy> iterator;
typedef YieldConstIterator<ResTy, IndexTy> const_iterator;
GeneratorCollection(range_t range, const yield_function_t &yieldF) :
mRange(range),
mYieldFunction(yieldF) {}
iterator begin() {
return iterator(mRange.begin, mYieldFunction);
}
iterator end() {
return iterator(mRange.end, mYieldFunction);
}
const_iterator begin() const {
return const_iterator(mRange.begin, mYieldFunction);
}
const_iterator end() const {
return const_iterator(mRange.end, mYieldFunction);
}
private:
range_t mRange;
yield_function_t mYieldFunction;
};
template<typename ResTy, typename IndexTy>
class Generator {
public:
typedef IndexTy index_t;
typedef ResTy res_t;
typedef typename yield_function<res_t, index_t>::type yield_function_t;
typedef Generator<ResTy, IndexTy> mytype_t;
typedef Range<IndexTy> parent_t;
typedef GeneratorCollection<ResTy, IndexTy> finalized_emitter_t;
typedef Range<IndexTy> range_t;
protected:
Generator(range_t range) : mRange(range) {}
public:
static mytype_t on_range(index_t begin, index_t end) {
return mytype_t({ begin, end });
}
finalized_emitter_t yield(yield_function_t f) {
return finalized_emitter_t(mRange, f);
}
protected:
range_t mRange;
};