Hello,
Do anyone know if how to implement something like istruction C# "yield" ??? (it permit to return a value (eg during a loop for) to another function and keep alive the environment).
Hello,
Do anyone know if how to implement something like istruction C# "yield" ??? (it permit to return a value (eg during a loop for) to another function and keep alive the environment).
Regards
Actually this instruction is not C# originated. I know it was present in at least Python before that. The easiest way is to use a static local variable holding the last returned result and continue from there during the next call.
Qt Code:
int getNextNatural(bool restart=false){ static int last = -1; if(restart) last = -1; return ++last; }To copy to clipboard, switch view to plain text mode
But I meant a bit more...
when a Elements is ok, it's returned to foo1 and printed; after the control goes again inside checkForSOmething() (exactlly after the yield) and it restart from inside for at point it left......Qt Code:
vector<Element> Elements // 20 elements suppose foo1() { foreach (Element e in checkForSomething(e)) { print (e.name); } IEnumerable<Elemement> checkForSomething(e) { //iterator on Elements = eIt int a = 10; //it'll keep alive for(; eIt.MoveNext() ) { //movNext go on..... if (e.value ==2) yield return e; } } //main foo1();To copy to clipboard, switch view to plain text mode
Regards
Exactly what my code does... Make the iterator static and voila...
Qt Code:
... { static XXX::const_iterator iter = e.begin(); while(iter!=e.end()){ //... return sth; // yields the iteration } }To copy to clipboard, switch view to plain text mode
Next time you call the method, it will skip the initialization of the iterator and continue from where it left.
yes, I could declare as static 'a' too....but when are these 'static' variabile deallocated? When program end, I guess...
Regards
I don't know what "a" does in your case because you don't use it anywhere, but yes, you may declare it static as well Static variables are never deallocated. They are destroyed together with global variables.
Hello,
'a' does nothing in my case. I'm looking for C# vs C++; with your code it's possibile to have something similar to yield; BUT: in my example what happen inside "for (moveNext)" is very simple; if I had many variabile, eg. "int a,b,c,d" or some large objects, I guess I have to declare they as statics -> they'll be keep alive until the application end! It seems a very waste of memory. Are we sure what is behind yield istruction does the same thing?? (ie work as "static" c++).
Thank in advance.
Regards
Look - you are trying to emulate a construction of another language that doesn't exist in C++, so you have to accept some drawbacks of such solutions. I'm sure you can try to emulate yield using some mapping between objects and their current states to avoid static variables, but it's a bit more work. C# also has to keep those objects in memory because you might always want to call the function again and the state of the run has to be kept somewhere.
But this is all unimportant - what is important is that C++ doesn't use a construction such as yield. In C++ you'd simply use an iterator passing it as an argument to the method (maybe even as a reference), like so:
Qt Code:
int func(std::vector<int>::const_iterator &iter){ int val = *iter; ++iter; return val*2; }To copy to clipboard, switch view to plain text mode
In this function iter gets updated to point to the next entry, so next time you call the function, it will operate on the next index (provided that the iterator remains valid and unchanged).
Actually it should be possible to emulate the whole IEnumerable interface with a class wrapping around a simple list structure.
"If you lie to the compiler, it will get its revenge." - Henry Spencer
Isn't it what iterators do?
"If you lie to the compiler, it will get its revenge." - Henry Spencer
Consider the following example:
Isn't this exactly what is searched for? And this is exactly a typical iterator. Of course hasNext() and next() have to be implemented in such a way that they perform the same function what the yieldable function does.Qt Code:
SomeContainerObject Elements; MyIterator iter(Elements); while(iter.hasNext()){ Element e = iter.next(); doSomething(e); }To copy to clipboard, switch view to plain text mode
What is vital is that the iterator keeps an internal state of "index" in the iterated object. Then it's just a matter of generating elements. Of course the object doesn't even have to be a container - in that case the iterator becomes a simple generator function, like this:
The above object keeps returning negations of increasing numbers starting from the number passed as the argument for the generator. It's similar to:Qt Code:
class Generator { public: Generator(int start){ m_curr = start; } bool hasNext(){ return true; /* neverending story */ } int next(){ return -(m_curr++); } private: int m_curr; }To copy to clipboard, switch view to plain text mode
Qt Code:
int fun(int s){ int x = s; while(1){ int r = -x; x = x+1; yield r; } }To copy to clipboard, switch view to plain text mode
Bookmarks