【问题标题】:Why stl vector can't contain coroutine objects?为什么 stl 向量不能包含协程对象?
【发布时间】:2013-11-22 22:02:44
【问题描述】:

我在 boost1.53 中使用协程,请看下面我的代码:

boost::coroutines::coroutine<int()> f(std::bind(foo, ...));
std::vector<decltype(f)> container; // it can be compiled
container.push_back(f); // compile error

错误:

no matching function for call to ‘std::vector<boost::coroutines::coroutine<int(),0> >::vector(paracel::coroutine<int>&)’

更新:发生错误是因为“boost::coroutines::coroutine”中没有复制构造/运算符,这里的情况是我只想将“f”保存到将索引映射到“f”的容器中.

我也试过unordered_map,emplace_back,还是不行!

如何让它在 C++ 中工作?

更新2: 我尝试了vector,unordered_map,map以及emplace_back,push_back,std :: move,但都失败了。 但是列表和双端队列可以使用 push_back/emplace_back 和 std::move:

std::deque<decltype(f)> container1;
container.push_back(std::move(f)); // ok
std::deque<decltype(f)> container2;
container.emplace_back(std::move(f)); // ok
std::list<decltype(f)> container3;
container.push_back(std::move(f)); // ok
std::list<decltype(f)> container4;
container.emplace_back(std::move(f)); // ok

为什么?

【问题讨论】:

    标签: c++ boost c++11 stl coroutine


    【解决方案1】:

    看起来boost::coroutines::coroutines&lt;int()&gt; 不支持复制构造函数。但是,您尝试 push_back() 一个左值。不过,您可能想尝试将对象移动到向量中:

    container.push_back(std::move(f));
    

    【讨论】:

    • 如果要放入向量中的类型既不可复制也不可移动,则它将不起作用。您需要使用不同的容器,例如 std::deque&lt;...&gt;std::list&lt;...&gt;emplace_back() 对象。
    【解决方案2】:

    如果您检查例如this reference 你会看到包含的类型

    T必须满足CopyAssignableCopyConstructible的要求。

    对元素的要求取决于对容器执行的实际操作。一般要求元素类型满足MoveConstructibleMoveAssignable的要求,但很多成员函数的要求更严格。

    如果您检查coroutine class,您会发现它既没有复制赋值运算符也没有复制构造函数。它确实有这些的移动变体,但正如上面第二段所述,这并不总是足够的。

    【讨论】:

    • @xunzhang:我不确定这是否足够,但使用emplace_back 而不是push_back 可能是一个开始。
    【解决方案3】:

    我使用 Boost 1.54,它适用于我的 g++4.8.2 和带有 libc++ 的 clang-3.4:

    #include <iostream>
    #include <vector>
    #include <boost/coroutine/coroutine.hpp>
    
    typedef boost::coroutines::coroutine<int()> coro_t;
    
    void f(coro_t::caller_type& ca)
    {
       ca(42);
    }
    
    int main()
    {
       std::vector<coro_t> coros;
       coro_t foo(&f);
       coros.push_back(std::move(foo));
       coros.emplace_back(&f);
       for(auto& coro : coros)
          std::cout << coro.get() << std::endl;
    }
    

    我将推测您没有工作的标准库,或者 boost 1.53 协程中的移动分配不是 noexcept(您可以使用 std::is_nothrow_move_assignable 检查)。

    【讨论】:

      【解决方案4】:

      两种可能:

      1.) 在 freestore 上分配协程:

      std::vector< shared_ptr< coroutine< void >::pull_type > v;
      v.push_back( new coroutine< void >::pull_type(...) );
      

      2.) 使用 moveaware-container (boost.container):

      boost::container::vector< coroutine< void >::pull_type > v;
      coroutine< void >::pull_type c(...)
      v.push_back( boost::move( c) );
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-07-24
        • 2013-03-14
        • 1970-01-01
        • 2021-12-15
        • 1970-01-01
        • 2020-12-26
        • 1970-01-01
        相关资源
        最近更新 更多