std :: vector,std :: move和指针失效

时间:2017-05-15 20:47:38

标签: c++ pointers iterator stdvector stdmove

我的问题涉及以下模式...... 我想使用以下模式构建一个昂贵的构造SomeData,然后将其移动到UsesData

所以问题是......

ud.dat.m_ptrs中的指针是否仍然有效?

struct BigObject{};
struct SomeData
{
    SomeData() = default;

    SomeData(const SomeData &) = delete;
    SomeData & operator = (const SomeData &) = delete;

    SomeData(SomeData &&) = default;
    SomeData & operator = (SomeData &&) = default;

    std::vector<BigObject> m_data1; // big vector
    std::vector<BigObject> m_data2; // big vector

    // (m_ptrs.size() == m_data1.size() + m_data2.size())
    // points to elements in m_data1 and m_data2...
    std::vector<const BigObject * const> m_ptrs;
};

struct Builder
{
    Builder() = delete;
    Builder(const Builder &) = delete;
    Builder & operator=(const Builder &) = delete;
    Builder(Builder &&) = delete;
    Builder & operator=(Builder &&) = delete;

    Builder(int a)  
    {
        // makes sure BigObject vectors in SomeDate are constructed correctly
        // builds m_ptrs... vector of ptrs to m_data1 and m_data2
    }

    SomeData dat;
};

struct UsesData
{
    UsesData() = delete;
    UsesData(const UsesData &) = delete;
    UsesData & operator=(const UsesData &) = delete;
    UsesData(UsesData &&) = delete;
    UsesData & operator=(UsesData &&) = delete;

    UsesData(Builder && from) : dat{ std::move(from.dat) }
    {}

    const SomeData dat;
};

int main()
{
    UsesData ud{ Builder{ 1 } };
    //...
}

1 个答案:

答案 0 :(得分:2)

指针仍然有效。根据{{​​1}} move constructor的行为:

  

在集装箱移动施工(超载(6))之后,参考,   其他指针和迭代器(除了结束迭代器)仍然存在   有效,但请参考std::vector中现在的元素。目前   标准通过一揽子声明提供此保证   §23.2.1[container.requirements.general] / 12,更直接   通过LWG 2321正在考虑保证。

这意味着,在移动之后,指针仍然有效并指向移动到新*this的元素。