Voglio sapere come implementare un generatore, come Python, in C++? Python può usare la parola chiave "rendimento" per farlo. Ma come farlo in C++?Come posso implementare un generatore in C++?
risposta
Non puoi farlo, davvero, ma puoi fingere. Ecco lo a way you can fake it in C, che puoi usare anche in C++.
+1 esattamente quello che stavo per dire, anche se non c'è davvero alcuna differenza tra "finirlo" e "implementarlo". Sospetto che in C++ si possa desiderare lo stato di coroutine nelle variabili membro di un functor e chiamarlo, con istanze diverse dove appropriato, invece di usare globals e chiamare una funzione con nome come fa anakin. Puoi fare una cosa simile in C con un parametro extra, ma è meno probabile che lo desideri. –
Chiamare una coroutine più volte e ottenere risposte diverse significa mantenere uno stato. Il modo per mantenere uno stato sono gli oggetti. Il modo per farli sembrare chiamata di funzione è l'overloading dell'operatore. Vedi http://en.wikipedia.org/wiki/Function_object.
In C++ abbiamo "iteratori". Uno chiede esplicitamente un interatore, lo accresce esplicitamente e lo denota.
Se si desidera che vengano utilizzati con le funzioni di libreria standard, dovrebbero essere principalmente derivati da std::forward_iterator
e implementare un numero di sue funzioni.
Un altro modo per imitare kindof un generatore su una collezione sta permettendo una funzione come argomento di una funzione di membro che si nutre (rendimenti) tutti i suoi valori a quella funzione:
struct MyCollection {
int values[30];
template< typename F >
void generate(F& yield_function) const {
int* end = values+30; // make this better in your own code :)
for(auto i: values) yield_function(*i);
}
};
// usage:
c.generate([](int i){ std::cout << i << std::endl; });
// or pre-C++11:
struct MyFunction {
void operator() (int i)const { printf("%d\n", i); }
};
MyCollection c;
c.generate(MyFunction());
Per approfondire l'iteratore implementazione: questo è un esempio. Può essere usato come variabile di ciclo o in algoritmi std.
#include <iterator>
template< typename T, typename TDiff = T >
struct TGenerator : public std::iterator<std::forward_iterator_tag,T,TDiff> {
T from,to;
T value;
TDiff step;
bool issentinel;
TGenerator(T from, T to, TDiff step, bool sentinel = false)
: from(from),to(to),step(step),issentinel(sentinel), value(from)
{}
void operator++(){ value += step; }
const T& operator*()const { return value; }
bool operator!=(const TGenerator& other) const {
return value<to;
}
TGenerator sentinel()const { return TGenerator(0,0,0,true); }
};
#include <algorithm>
#include <iostream>
int main()
{
TGenerator<int> i(0,10,3);
std::copy(i, i.sentinel(), std::ostream_iterator<int>(std::cout, " "));
return 0;
}
è possibile utilizzare boost.context (spiacente, non sulla distribuzione spinta ancora, dovrete ottenere da boost vault).
Un codice tipico esempio potrebbe essere simile a questo:
#include <iostream>
#include <boost/context.hpp>
using namespace std;
struct Parameters {
int par1;
float par2;
};
boost::context c1;
boost::context c2;
void F(void* parameters) {
Parameters& pars = *(Parameters*)parameters;
cout << pars.par1 << endl;
c2.jump_to(c1);
cout << pars.par2 << endl;
};
int main() {
c1 = boost::context::current();
Parameters p;
p.par1 = 8;
c2 = boost::context::create_context(F , c1 , p);
c1.jump_to(c2);
p.par2 = 1.3;
c1.jump_to(c2);
}
Questa ... Signori ... è pura MAGIA NERA:
http://www.codeproject.com/Articles/29524/Generators-in-C
ho provato, ed è funziona anche in modo ricorsivo. L'ho usato regolarmente da allora. Generatori, quasi come cittadini di prima classe in C++. Non c'è nemmeno un sovraccarico di prestazioni.
Con il mio più profondo rispetto all'autore
Non è _that_ black magic ... tuttavia, è molto un-C++ 11-ish. – einpoklum
- 1. Come posso implementare IRandomAccessStream in C#?
- 2. Posso memoizzare un generatore Python?
- 3. Come posso convertire un testo in un generatore di test?
- 4. Come implementare un grapher in C#
- 5. Come posso implementare questa logica
- 6. Come posso implementare SlideShow in Android?
- 7. python: quando posso decomprimere un generatore?
- 8. Come posso implementare java.awt.Composite in modo efficiente?
- 9. C# generatore costruttore copia
- 10. Come funziona un generatore di numeri casuali?
- 11. Come posso codificare un monitor in C?
- 12. Come posso implementare l'algoritmo di unificazione in un linguaggio come Java o C#?
- 13. Implementare un server WebDAV in C#?
- 14. Come posso implementare un OutputStream che posso riavvolgere?
- 15. Come implementare il pattern Observer in C++
- 16. Implementare un server Comet in C#
- 17. Come implementare un linguaggio di scripting in un'applicazione C?
- 18. Come posso implementare un'interfaccia comparabile in go?
- 19. Come posso implementare un tipo di dati stringa in LLVM?
- 20. enumerate() - un generatore in Python
- 21. Come posso creare un generatore di tabelle di verità?
- 22. Come implementare il polimorfismo generico in C#?
- 23. Come posso implementare l'interfaccia Iterable?
- 24. Come implementare una matrice enorme in C
- 25. Come implementare l'incapsulamento condizionale in C#
- 26. come implementare le interfacce in C++?
- 27. Come implementare CAS in C++ 11
- 28. Come implementare la serializzazione in C++
- 29. Come implementare correttamente i plugin in C#?
- 30. Come posso forzare l'ereditazione delle classi per implementare un metodo statico in C#?
presto, saremo in grado di aggiungere una risposta con le coroutine C++ 20. – xtofl