Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python's yield feature in C/C++? [duplicate]

Tags:

c++

python

yield

c

I just learned about the yield keyword in python - very impressive and useful indeed.

is there any equivalent in C and C++ languages?

like image 618
yigal Avatar asked Dec 04 '13 18:12

yigal


Video Answer


2 Answers

Not yield as such, although you can write lazy iterators using std::iterator (see this answer). Rather than having yield as in Python, you return the next element from operator++.

like image 129
kindall Avatar answered Sep 25 '22 03:09

kindall


No.

Implementing yield requires suspending execution and that doesn't fit well with C++ model where there is only one stack(1). The only way to implement a general yield requires going at a lower level than C++ (i.e. managing the stack and execution context explicitly), something that cannot be done portably at the C++ level.

(1) C++11 introduced portable threads, and this means there can be multiple stacks and therefore you can mimic coroutines (probably quite inefficiently): for example

#include <stdio.h>
#include <thread>
#include <mutex>

template<typename RV>
struct Generator {
    std::mutex a, b;
    bool done;
    RV *current;

    Generator() : done(false) {
        b.lock();
        std::thread([this](){ this->call_run(); }).detach();
    }

    void call_run() {
        this->run();
        done = true;
    }

    virtual void run() = 0;

    void yield(const RV & x) {
        a.lock();
        *current = x;
        b.unlock();
    }

    bool next(RV & res) {
        if (done) return false;
        current = &res;
        a.unlock();
        b.lock();
        return true;
    }
};

///////////////////////////////////////////////////////

struct Squares : Generator<int> {
    void run() override {
        for (int i=0; i<10; i++) {
            yield(i*i);
        }
    }
};

int main() {
    Squares sq;
    int x = -1;
    while(sq.next(x)) {
        printf("%i\n", x);
    }
    return 0;
}
like image 31
6502 Avatar answered Sep 25 '22 03:09

6502