为什么stl vector不能包含coroutine对象?

时间:2013-11-11 07:05:23

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

我在boost1.53中使用coroutine,请参阅下面的代码:

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 ++中运行?

UPDATE2: 我尝试了vector,unordered_map,与emplace_back,push_back,std :: move一起映射,并且都失败了。 但是list和deque可以使用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

为什么?

4 个答案:

答案 0 :(得分:8)

看起来好像boost::coroutines::coroutines<int()>不支持复制构造函数。但是,您尝试push_back()左值。您可能想尝试将对象移动到矢量中,但是:

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

答案 1 :(得分:3)

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

  

T必须符合CopyAssignableCopyConstructible的要求。

  

对元素施加的要求取决于对容器执行的实际操作。通常,要求元素类型满足MoveConstructibleMoveAssignable的要求,但许多成员函数强加了更严格的要求。

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

答案 2 :(得分:1)

我使用的是Boost 1.54,它适用于g ++ 4.8.2和clang-3.4以及libc ++:

#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检查它。)

答案 3 :(得分:0)

两种可能性:

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) );