Использование варианта 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<ReportS‌​tatusRequest, 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<ReportS‌​tatusRequest,
                        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,

Другие вопросы по тегам