Je veux savoir comment mettre en œuvre un générateur, comme Python, en C ++? Python peut utiliser le mot-clé "RENDU" pour le faire. Mais comment le faire en C ++? P>
6 Réponses :
Vous ne pouvez pas le faire, vraiment, mais vous pouvez le simuler. Voici Une manière que vous pouvez simuler en C , que vous pouvez utiliser en C ++ aussi. P>
+1 Ce que j'allais dire exactement, bien qu'il n'y ait pas vraiment de différence entre "le freiner" et "la mettre en œuvre". Je soupçonne qu'en C ++, vous pourriez souhaiter l'état de Coroutin dans des variables de membre d'un foncteur et l'appelant, avec des cas différents, au lieu d'utiliser des globaux et d'appeler une fonction nommée en fonction de l'anakin. Vous pouvez faire une chose similaire en C avec un paramètre supplémentaire, mais moins susceptibles de vouloir.
appeler une coroutine plusieurs fois et obtenir des réponses différentes signifie que vous gardez un État. Le moyen de garder un état est des objets. Le moyen de les faire ressembler à une fonction de fonction est la surcharge de l'opérateur. Voir http://fr.wikipedia.org/wiki/function_Object . P>
en C ++, nous avons des "itérateurs". On demande explicitement une interacatrice, incrémente explicitement elle et les déréférences qu'elle.
Si vous souhaitez qu'ils soient utilisés avec les fonctions de la bibliothèque standard, ils devraient principalement être dérivés de Une autre façon d'imiter un générateur d'un générateur sur une collection permet une fonction comme argument d'une fonction membre qui se nourrit (rendement) toutes les valeurs de cette fonction: P > std :: Forwe_Prodator code> et implémentent Un certain nombre de fonctions de ce type. p>
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() );
Élaborer sur la mise en œuvre de l'itérateur: c'est un exemple. Il peut être utilisé comme variable de boucle ou dans des algorithmes 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; }
Vous pouvez utiliser boost.context strong> (Désolé, pas sur la distribution de Boost Pourtant, vous devrez l'obtenir de Boost Vault ). Un exemple d'exemple typique serait comme ceci: p>
Ceci ... Messieurs ... est Pure Black Magic: P>
Ce n'est pas que i> la magie noire ... Cependant, c'est très un-C ++ 11-ish.
Bientôt, nous pourrons ajouter une réponse avec les Coroutines C ++ 20.