Использование варианта Boost с разными типами shared_ptr<T>
Я хочу использовать Boost:: Вариант для эффективного объединения нескольких различных типов следующим образом.
using VariantType = boost::variant<
std::shared_ptr<StructA>,
std::shared_ptr<StructB>
>;
Я собрал прототип на Coliru, где он по крайней мере компилируется.
VariantType variant = std::make_shared<StructA>(1, 'a', 3);
boost::apply_visitor(output{}, variant);
std::cout << variant.which() << std::endl;
variant = std::make_shared<StructB>('b', 'c');
boost::apply_visitor(output{}, variant);
std::cout << variant.which() << std::endl;
распечатывает следующее как ожидалось:
g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp -lrt && ./a.out
StructA: CommonStruct: 123 1a3
0
StructB: CommonStruct: 456 bc
1
Теперь о сути вопроса, фактический код (который прекрасно работает в Visual Studio 2015), однако он не компилируется в gcc 4.9.1. (с различными типами вместо StructA и StructB выше). Может ли кто-нибудь помочь мне понять, что означает это загадочное сообщение об ошибке и как его обойти. Все мои структуры являются структурами POD с явными конструкторами, похожими на структуры StructA и StructB.
Вот сообщение об ошибке gcc 4.9.1.
error: call of overloaded 'initialize(void*, boost::move_detail::remove_reference<std::unique_ptr<ReportStatusRequest, std::default_elete<ReportStatusRequest> >&>::type)' is ambiguous.
)
^
/spare1/aaron/0339/ltib/rootfs/usr/include/boost/variant/variant.hpp:1561:17: note: candidates are:
In file included from /spare1/aaron/0339/ltib/rootfs/usr/include/boost/variant/variant.hpp:30:0,
from /spare1/aaron/0339/ltib/rootfs/usr/include/boost/variant.hpp:17,
from ../../include/fhdb/FHDBUtil.h:17,
from FHDBUtil.cpp:18:
Эта ошибка возникает для каждого из типов вариантов в определении типа GenericSendMessage (показано ниже). Каждое из этих сообщений об ошибках сопровождается рядом предупреждений gcc note следующим образом:
/usr/include/boost/variant/detail/initializer.hpp:115:24: note: static int boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::initialize(void*, boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param2_T) [with BaseIndexPair = boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::make_initializer_node::apply<boost::mpl::pair<boost::detail::variant::initializer_root, mpl_::int_<0> >, boost::mpl::l_iter<boost::mpl::list6<std::shared_ptr<ConnectRequest>, std::shared_ptr<DisconnectRequest>, std::shared_ptr<GenerateFHDBRequest>, std::shared_ptr<ReportStatusRequest>, std::shared_ptr<RetrieveFHDBRequest>, std::shared_ptr<RetrieveComplete> > > >::initializer_node, mpl_::int_<1> >, boost::mpl::l_iter<boost::mpl::list5<std::shared_ptr<DisconnectRequest>, std::shared_ptr<GenerateFHDBRequest>, std::shared_ptr<ReportStatusRequest>, std::shared_ptr<RetrieveFHDBRequest>, std::shared_ptr<RetrieveComplete> > > >::initializer_node, mpl_::int_<2> >, boost::mpl::l_iter<boost::mpl::list4<std::shared_ptr<GenerateFHDBRequest>, std::shared_ptr<ReportStatusRequest>, std::shared_ptr<RetrieveFHDBRequest>, std::shared_ptr<RetrieveComplete> > > >::initializer_node, mpl_::int_<3> >, boost::mpl::l_iter<boost::mpl::list3<std::shared_ptr<ReportStatusRequest>, std::shared_ptr<RetrieveFHDBRequest>, std::shared_ptr<RetrieveComplete> > > >::initializer_node, mpl_::int_<4> >; Iterator = boost::mpl::l_iter<boost::mpl::list2<std::shared_ptr<RetrieveFHDBRequest>, std::shared_ptr<RetrieveComplete> > >; boost::detail::variant::make_initializer_node::apply<BaseIndexPair, Iterator>::initializer_node::param2_T = std::shared_ptr<RetrieveFHDBRequest>&&]
static int initialize(void* dest, param2_T operand)
Это сообщение об ошибке соответствует фактическому типу VariantType, указанному ниже.
using GenericSendMessage = boost::variant<
std::shared_ptr<ConnectRequest>,
std::shared_ptr<DisconnectRequest>,
std::shared_ptr<GenerateFHDBRequest>,
std::shared_ptr<ReportStatusRequest>,
std::shared_ptr<RetrieveFHDBRequest>,
std::shared_ptr<RetrieveComplete>
>;
1 ответ
Ваше сообщение об ошибке гласит:
error: call of overloaded
'initialize(void*,
boost::move_detail::remove_reference<
std::unique_ptr<ReportStatusRequest,
std::default_delete<ReportStatusRequest> >&>::type)' is ambiguous.
Обратите внимание unique_ptr
часть! Это говорит о том, что вы пытаетесь назначить unique_ptr
к типу варианта.
Это действительно не компилируется в gcc-4.9: /questions/22101956/sborki-ispolzuyuschie-kod-c-20-skompilirovannyie-s-c-30/22101962#22101962
Но он компилируется в более поздних версиях gcc.
решение: назначить shared_ptr
вместо unique_ptr
,