将boost变体与不同的shared_ptr <t>类型

时间:2016-08-22 20:01:50

标签: gcc boost c++14 shared-ptr boost-variant

我想使用boost :: variant来有效地保存几种不同类型的并集,如下所示。

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&amp; StructB)。有人可以帮我弄清楚这个神秘错误信息的含义是什么以及如何解决它。我的所有结构都是具有类似于StructA和StructB中的显式构造函数的POD结构。

这是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 typedef(稍后显示)中的每个变体类型都会出现此错误。这些错误消息中的每一个都附有一些gcc注释警告,如下所示:

/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 个答案:

答案 0 :(得分:0)

您的错误消息指出:

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中编译:http://coliru.stacked-crooked.com/a/9526f8c3e724b5c7

但它确实在后来的gcc版本中编译。

<强>溶液: 分配shared_ptr而不是unique_ptr