繁体   English   中英

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

[英]std::vector, std::move and pointer invalidation

我的问题与以下模式有关...我想使用以下模式来构造一个昂贵的构造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 } };
    //...
}

指针将保持有效。 根据std::vectormove构造函数的行为:

在容器移动构造(重载(6))之后,对other的引用,指针和迭代器(最终迭代器除外)仍然有效,但是引用的是*this元素。 当前标准通过§23.2.1[container.requirements.general] / 12中的一揽子声明来提供此保证,并且正在通过LWG 2321考虑更直接的保证。

这意味着,在移动之后,指针保持有效,并指向被移动到新std::vector的元素。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM