boost :: variant:递归向量类型的奇怪行为

时间:2016-05-11 17:21:03

标签: c++ recursion boost vector boost-variant

我有一个有一个成员的类,它是两个类型的boost::variant:一个vector个整数和一个vector包含的类对象(后者显然需要是在recursive_wrapper的帮助下完成。该类的代码在

之下
#include <boost/variant/variant.hpp>
#include <boost/variant/recursive_wrapper.hpp>

#include <vector>

class TestVariant
{
public:

    typedef boost::variant< std::vector<int>, boost::recursive_wrapper<std::vector<TestVariant> > > StorageType;

    TestVariant():
        m_value{ std::vector<int>{} }
    {}

    TestVariant(const TestVariant& other):
        m_value{ other.m_value }
    {}

    TestVariant& operator=(const TestVariant& other)
    {
        m_value = other.m_value;

        return *this;
    }

    TestVariant(TestVariant&& other):
        m_value{ std::move(other.m_value) }
    {}

    TestVariant& operator=(TestVariant&& other)
    {
        m_value = std::move(other.m_value);

        return *this;
    }

    TestVariant(const std::vector<int>& value):
        m_value{ value }
    {}

    TestVariant(std::vector<int>&& value):
        m_value{ std::move(value) }
    {}

    TestVariant(const std::vector<TestVariant>& value):
        m_value{ value }
    {}

    TestVariant(std::vector<TestVariant>&& value):
        m_value{ std::move(value) }
    {}

private:

    StorageType m_value;
};

当我尝试使用此类创建vector TestVariant并安装TestVariant的递归实例的实例时,如下所示

std::vector<TestVariant> v;

v.emplace_back(std::vector<TestVariant>{ std::vector<TestVariant>{}, std::vector<int>{} }); // access violation!

我在MSVS 2013和Boost ver 1.53下获得了“访问冲突”异常(我知道这是Boost的旧版本,但我目前在组织上限制使用它)。 coliru上的相同代码工作正常(请参阅here)。

更奇怪的是,如果我切换两个向量的顺序,MSVS 2013中的一切似乎都没问题

std::vector<TestVariant> v;

v.emplace_back(std::vector<TestVariant>{std::vector<int>{}, std::vector<TestVariant>{} }); // works!

有什么想法吗?我一直试图解决这个问题一天......

1 个答案:

答案 0 :(得分:0)

这确实似乎是统一初始化/初始化列表中的许多错误之一。代码“很好”(从某种意义上说,它不会触发UB)

如果它与我遇到的错误类似,你可以尝试明确指定类型名称:

v.emplace_back(std::vector<TestVariant>{ 
     TestVariant(std::vector<TestVariant>{}), 
     TestVariant(std::vector<int>{}) });