генератор для boost :: fusion :: map инициализации с некопируемым типом значения

Я хотел бы создать базовый класс, который может содержать N сокетов. Это сокеты ZeroMQ, и они не могут быть скопированы. В этом случае базовый класс может в общем случае реализовывать поведение завершения работы на управляемых сокетах и ​​других сервисных функциях. Принимая во внимание, что производные классы могут получить доступ к требуемому сокету, используя тип тега.

Моя идея заключалась в использовании boost::fusion::map, Типы сокетов не являются конструктивными по умолчанию, поэтому мне нужно передать в качестве параметров: ссылку на контекст и int, идентифицирующие тип сокета (ZMQ_{SOCKET_TYPE} который int). Наконец, должна быть функция генератора для создания socket_t быть помещенным в fusion::map, Идея состоит в том, чтобы использовать fusion::repetitive_view прямо сейчас, так как сокеты имеют все одинаковые параметры инициализации.

Проблема сейчас заключается в том, что: если я вручную передам socket_t{context, int}, socket_t{context, int} экземпляры к fusion::map ctor все просто отлично работает. Использование генератора приводит к компиляции, утверждающей, что socket_t не копируется

Вот упрощенный код, который я пытаюсь скомпилировать:

#include <boost/mpl/transform.hpp>
#include <boost/fusion/include/pair.hpp>

#include <boost/fusion/include/map.hpp>
#include <boost/fusion/container/generation/make_vector.hpp>using namespace std;
namespace mpl = boost::mpl;
namespace fus = boost::fusion;

struct context_t : boost::noncopyable
{};

struct socket_t : boost::noncopyable
{
socket_t(context_t& context, int type) : context_{&context}, type_{type}
{}

socket_t(socket_t&& s) : context_{s.context_}, type_{s.type_}
{}

socket_t& operator=(socket_t&& s)
{
context_ = s.context_;
type_ = s.type_;
return *this;
}

void use_fields()const
{ // just to avoid warnings that fields are not used
(void)context_;
(void)type_;
}

private:
context_t* context_;
int type_;
};

// we need a view of keys in conjunction with the context
template<class T>
auto infinite_context(fus::vector<T> v)
{
return fus::repetitive_view<fus::vector<T>>{v};
}template<class... Pairs>
struct base_type
{
typedef fus::map<Pairs...> tagged_map;

base_type() : context_{} //, sockets_{}
{}

context_t context_;
//fus::map<Pairs...> sockets_;
};

struct tag1 {};
struct tag2 {};int main(int argc, char* argv[])
{
context_t c;

typedef base_type<fus::pair<tag1, socket_t>, fus::pair<tag2, socket_t>> test_me_type;auto g = infinite_context(fus::make_vector([&c]()->socket_t{ return {c, 1}; }));

test_me_type::tagged_map m1{socket_t{c, 1}, socket_t{c, 1}}; //OK
//test_me_type::tagged_map m2{g}; //Error: access to deleted copy ctor!

(void)g;
(void)m1;
//(void)m2;

return 0;
}

ИМО проблема в том, что fusion::vector экземпляр используется в fusion::repetitive_view становится не копируемым … Таким образом, генерация невозможна. Как можно сгенерировать и переслать N socket_t экземпляры к fusion::map?

2

Решение

ОК решил это.

Ключ должен был представить копируемый прокси-объект, который имеет неявный оператор преобразования в fusion::pair<TagType, socket_t>, Отсутствующий фрагмент:

struct convertible
{
convertible(context_t& c, int t)
: c_{&c}
, t_{t}
{}

template<class Tag>
operator fus::pair<Tag, socket_t>()const
{
return socket_t{*c_, t_};
}

private:
context_t* c_;
int t_;
};

int main(int argc, char* argv[])
{
context_t c;

typedef base_type<fus::pair<tag1, socket_t>, fus::pair<tag2, socket_t>> test_me_type;

auto g = infinite_context(fus::make_vector(convertible{c, 1}));

test_me_type::tagged_map m1{socket_t{c, 1}, socket_t{c, 1}}; //OK
test_me_type::tagged_map m2{g}; //OK as well!(void)g;
(void)m1;
(void)m2;

return 0;
}
2

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

Других решений пока нет …

По вопросам рекламы [email protected]