Почему вектор stl не может содержать объекты сопрограмм?

Я использую сопрограмму в 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 ++?

Update2:
Я попробовал vector, unordered_map, 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

Зачем?

2

Решение

Это выглядит, как если бы boost::coroutines::coroutines<int()> не поддерживает конструктор копирования. Вы пытаетесь push_back() однако, lvalue. Вы можете попробовать переместить объект в вектор, хотя:

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

Другие решения

Если вы проверите, например, эта ссылка вы увидите, что содержащийся тип

Т должен соответствовать требованиям CopyAssignable а также CopyConstructible.

А также

Требования, предъявляемые к элементам, зависят от фактических операций, выполняемых над контейнером. Как правило, требуется, чтобы тип элемента соответствовал требованиям MoveConstructible а также MoveAssignable, но многие функции-члены предъявляют более строгие требования.

Если вы проверите coroutine учебный класс вы увидите, что у него нет ни оператора копирования-назначения, ни конструктора копирования. Это делать есть варианты ходов, но, как отмечалось во втором абзаце выше, этого не всегда достаточно.

3

Я использую 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 не исключение (вы можете проверить это с помощью std::is_nothrow_move_assignable).

1

две возможности:

1.) Распределить сопрограммы на freestore:

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

2.) использовать Moveaware-контейнер (boost.container):

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