如何用C ++ 20协程说Hello World?

时间:2019-05-17 11:29:21

标签: c++ generator c++20 c++-coroutine

出于学习目的,我尝试使用C ++ 20协程制作过于复杂的“ Hello World”程序:

HelloWorldMessage sayHelloToWorld()
{
    co_yield "Hello";
    co_yield " ";
    co_yield "World";
    co_yield "!";
}

int main() 
{
    for (auto w : sayHelloToWorld())
    {
        std::cout << w;
    }
}

主要基于最新的叮当警告消息以及uncomplete cppreference page和此example来准备这样的HelloWorldMessage生成器I。

所以我的结果如下。这里缺少什么?因为,我没有说“您好”,而是遇到了细分错误:

请参见link

struct HelloWorldState
{
    const char* currentWord = "<not value yet>";
    bool finalWord = false;
};

struct HelloWorldPromise
{
    HelloWorldState state;
    std::experimental::suspend_always initial_suspend() const noexcept { return {}; }
    std::experimental::suspend_always final_suspend() const noexcept { return {}; }

    std::experimental::suspend_always yield_value(const char* word) noexcept
    {
        state.currentWord = word;
        return {};
    }  

    std::experimental::suspend_always return_void() noexcept
    {
        state.finalWord = true;
        return {};
    }  

    auto& get_return_object() noexcept
    {
        return *this;
    }

    void unhandled_exception()
    {
        state.finalWord = true;
        throw;
    }
};

struct HelloWorldMessage
{
    using promise_type = HelloWorldPromise;
    using promise_handle = std::experimental::coroutine_handle<promise_type>;

    struct Iter
    {
        promise_handle handle = nullptr;
        HelloWorldState state;

        using iterator_category = std::input_iterator_tag;
        using value_type        = const char*;
        using difference_type   = ptrdiff_t;
        using pointer           = value_type const *;
        using reference         = value_type const &;

        reference operator * () const { assert(handle); return state.currentWord; }
        pointer operator -> () const { return std::addressof(operator*()); }

        bool operator == (const Iter& other) { return handle == other.handle; }
        bool operator != (const Iter& other) { return !(*this == other); }

        Iter() = default;
        Iter(promise_handle handle)
            : handle(handle)
        {
           assert(handle);
           next();
        }

        Iter& operator ++()
        {
            if (!handle)
                return *this;
            if (state.finalWord)
            {
                handle = nullptr;
                return *this;
            }
            next();
            return *this;
        }

        void next()
        {
            try {
                handle.resume();
                state = handle.promise().state;
            } catch (...) {
                std::cerr << "@%$#@%#@$% \n";
            }
        }

    };

    promise_handle handle = nullptr;
    HelloWorldMessage(promise_type& promise) : handle(promise_handle::from_promise(promise)) {}

    Iter begin() const { assert(handle); return {handle}; }
    Iter end() const { return {}; }
};

也许c还没有准备好?

1 个答案:

答案 0 :(得分:0)

一些错误:

首先-Promise应返回生成器对象,而不是对其自身的引用。因此正确的方法是:

@Entity
@Access(AccessType.PROPERTY)
@IdClass(PersoonSessieKey.class)
@Table(name = "PersoonSessie")
public class ClubPersoonSessie implements Serializable {

    private ClubSessie sessie;
    private ClubPersoon persoon;

    @Id
    @ManyToOne(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "SessieId")
    public ClubSessie getSessie() {
        return sessie;
    }

    public void setSessie(ClubSessie sessie) {
        this.sessie = sessie;
    }

    @Id
    @ManyToOne(cascade = CascadeType.PERSIST)
    @JoinColumn(name = "PersoonId")
    public ClubPersoon getPersoon() {
        return persoon;
    }

    public void setPersoon(ClubPersoon persoon) {
        this.persoon = persoon;
    }

    public ClubPersoonSessie() {
    }
}

下一步-终止和返回void可以简化为:

public class PersoonSessieKey implements Serializable {

    private int persoonId;
    private int sessieId;

    public int getPersoonId() {
        return persoonId;
    }

    public int getSessieId() {
        return sessieId;
    }

    public PersoonSessieKey(int persoonId, int sessieId) {
        this.persoonId = persoonId;
        this.sessieId = sessieId;
    }

    public PersoonSessieKey() {
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 89 * hash + this.persoonId;
        hash = 89 * hash + this.sessieId;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final PersoonSessieKey other = (PersoonSessieKey) obj;
        if (this.persoonId != other.persoonId) {
            return false;
        }
        if (this.sessieId != other.sessieId) {
            return false;
        }
        return true;
    }

}

下一步-在迭代器中-我们将依赖struct HelloWorldPromise { ... auto get_return_object(); ... }; struct HelloWorldMessage { ... }; auto HelloWorldPromise::get_return_object() { return HelloWorldMessage(*this); } -因此不需要void return_void() noexcept {} void unhandled_exception() { std::terminate(); } 。完整的迭代器来源是:

handle.done

还有完整的示例here

我对此2018/n4736.pdf进行了大部分更正。