【问题标题】:std::vector, std::move and pointer invalidationstd::vector、std::move 和指针失效
【发布时间】:2017-05-15 20:47:37
【问题描述】:

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

【问题讨论】:

    标签: c++ pointers iterator stdvector stdmove


    【解决方案1】:

    指针将保持有效。根据std::vectormove constructor的行为:

    容器移动构造后(重载(6)),引用, 指向其他的指针和迭代器(除了结束迭代器) 有效,但引用现在位于 *this 中的元素。目前的 标准通过一揽子声明做出此保证 §23.2.1[container.requirements.general]/12,以及更直接的 正在考虑通过LWG 2321 提供担保。

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

    【讨论】:

    • 是否知道主要编译器是否对此完全抱怨?
    • @Quantifeye 如果不与每个编译器确认就很难说;根据我的经验,gcc/clang 至少可以。
    猜你喜欢
    • 2017-05-28
    • 2017-10-19
    • 1970-01-01
    • 2011-03-18
    • 1970-01-01
    • 1970-01-01
    • 2013-12-08
    • 2013-06-18
    相关资源
    最近更新 更多