Skip to content

A strange compilation error occurs, seemingly related to set_stopped #174

@Cra3z

Description

@Cra3z

The intent of the following program is to print #1 in the main thread, then #2 in thread1, and finally #3 in thread2. Using stdexec, it compiles and runs as intended, but curiously, it fails to compile with beman::execution. see https://godbolt.org/z/71Mv3frGx

namespace {
    std::thread::id main_thread_id = std::this_thread::get_id();

    template<typename... Args>
    void debug(std::format_string<Args...> fmt, Args&&... args) {
        auto thread_id = std::this_thread::get_id();
        auto thread_name = thread_id == main_thread_id ? "main" : (std::stringstream{} << thread_id).str();
        std::clog << std::format("[thread-{}] {}\n", thread_name, std::format(fmt, std::forward<Args>(args)...));
    }
}

int main() {
    ex::run_loop ex_context1;
    std::jthread thread1{
        [&ex_context1] {
            debug("ex_context1 run...");
            ex_context1.run();
        }
    };

    ex::run_loop ex_context2;
    std::jthread thread2{
        [&ex_context2] {
            debug("ex_context2 run...");
            ex_context2.run();
        }
    };

    ex::sender auto snd = ex::just() | ex::then([] {
        debug("#1");
    }) | ex::continues_on(ex_context1.get_scheduler()) | ex::then([] {
        debug("#2");
    }) | ex::continues_on(ex_context2.get_scheduler()) | ex::then([] {
        debug("#3");
    });

    ex::sync_wait(snd);

    ex_context1.finish();
    ex_context2.finish();
}

I may have located where the compilation error occurs:

[]<typename Tag, typename... Args>(auto, auto& state, auto& receiver, Tag, Args&&... args) noexcept -> void {
using result_t = ::beman::execution::detail::decayed_tuple<Tag, Args...>;
constexpr bool nothrow = ::std::is_nothrow_constructible_v<result_t, Tag, Args...>;
try {
[&]() noexcept(nothrow) {
state.async_result.template emplace<result_t>(Tag(), std::forward<Args>(args)...);
}();
Here, Tag is beman::execution::set_stopped_t, state.async_result is a std::variant<std::monostate, std::tuple<beman::execution::set_value_t>, std::tuple<beman::execution::set_error_t, std::exception_ptr>>,
while result_t is std::tuple<beman::execution::set_stopped_t>, thus causing the compilation error when attempting to invoke emplace.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions