我的问题涉及以下模式......
我想使用以下模式构建一个昂贵的构造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 } };
//...
}
答案 0 :(得分:2)
指针仍然有效。根据{{1}} move constructor的行为:
在集装箱移动施工(超载(6))之后,参考, 其他指针和迭代器(除了结束迭代器)仍然存在 有效,但请参考
std::vector
中现在的元素。目前 标准通过一揽子声明提供此保证 §23.2.1[container.requirements.general] / 12,更直接 通过LWG 2321正在考虑保证。
这意味着,在移动之后,指针仍然有效并指向移动到新*this
的元素。