我在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
为什么?
答案 0 :(得分:8)
看起来好像boost::coroutines::coroutines<int()>
不支持复制构造函数。但是,您尝试push_back()
左值。您可能想尝试将对象移动到矢量中,但是:
container.push_back(std::move(f));
答案 1 :(得分:3)
如果你检查,例如this reference您将看到包含的类型
T必须符合CopyAssignable和CopyConstructible的要求。
和
对元素施加的要求取决于对容器执行的实际操作。通常,要求元素类型满足MoveConstructible和MoveAssignable的要求,但许多成员函数强加了更严格的要求。
如果检查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) );