2

我在 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

为什么?

4

4 回答 4

8

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

container.push_back(std::move(f));
于 2013-11-11T07:13:32.100 回答
3

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

T 必须满足CopyAssignableCopyConstructible的要求。

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

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

于 2013-11-11T07:11:25.910 回答
1

我使用 Boost 1.54,它适用于带有 libc++ 的 g++4.8.2 和 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)。

于 2013-11-11T12:45:57.333 回答
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) );
于 2013-11-11T10:46:05.103 回答