从标准容器中移动元素是否合法?
Is it legal to move elements from standard containers?
我正在写一个class,它需要高效的函数来过滤成员容器(比方说std::vector
)。此函数应具有类似于以下的界面:
void filter(std::vector<SomeType>& items, const std::vector<int>& inds);
该函数应使容器 items
处于以下状态:
- 应删除 inds
中索引指向的项目
- 其他物品应留在容器中以保持初始顺序。
为简单起见,我们假设 inds
是一个完美的容器,每个操作的复杂度为 O(1),并且所有索引都有效且没有重复。
我的想法是创建第二个容器,保留所需的 space,然后移动(通过 std::move
)每个未被 inds
索引的元素到这个新容器中;然后交换旧容器和新容器。
例如像这样:
void filter(std::vector<SomeType>& items, const std::vector<int>& inds)
{
std::vector<SomeType> new_items{};
new_items.reserve( items.size() - inds.size() );
for(size_t i = 0; i < items.size(); ++i)
if( contains( inds, i ) ) // magic O(1) function, never mind
new_items.push_back( std::move( items[i] ) );
items.swap(new_items);
}
我的问题是:
1) 在 vector
(或通常任何其他标准容器)内的某些元素上使用 std::move
后,是否会出现这些元素的双重破坏等问题?
2) 是否有一种标准方法可以有效地进行此类过滤?
防止搬家可能引起的问题不是集装箱的责任。只要被移动的项目的类型有一个定义明确且正确的移动构造函数/隐式移动构造函数,那么将项目从 items
移动到 new_items
就与任何其他移动操作相同;容器不会改变这一点。
简而言之,这个责任在于 class,而不是它所使用的容器。
您从中移出的对象处于有效但未指定的状态,并且可以在它们上调用没有前提条件的函数。并且析构函数必须是没有前提条件的函数。如果 SomeType
不满足此条件,则它是错误格式的。
所以不会有双重破坏的问题。
我正在写一个class,它需要高效的函数来过滤成员容器(比方说std::vector
)。此函数应具有类似于以下的界面:
void filter(std::vector<SomeType>& items, const std::vector<int>& inds);
该函数应使容器 items
处于以下状态:
- 应删除 inds
中索引指向的项目
- 其他物品应留在容器中以保持初始顺序。
为简单起见,我们假设 inds
是一个完美的容器,每个操作的复杂度为 O(1),并且所有索引都有效且没有重复。
我的想法是创建第二个容器,保留所需的 space,然后移动(通过 std::move
)每个未被 inds
索引的元素到这个新容器中;然后交换旧容器和新容器。
例如像这样:
void filter(std::vector<SomeType>& items, const std::vector<int>& inds)
{
std::vector<SomeType> new_items{};
new_items.reserve( items.size() - inds.size() );
for(size_t i = 0; i < items.size(); ++i)
if( contains( inds, i ) ) // magic O(1) function, never mind
new_items.push_back( std::move( items[i] ) );
items.swap(new_items);
}
我的问题是:
1) 在 vector
(或通常任何其他标准容器)内的某些元素上使用 std::move
后,是否会出现这些元素的双重破坏等问题?
2) 是否有一种标准方法可以有效地进行此类过滤?
防止搬家可能引起的问题不是集装箱的责任。只要被移动的项目的类型有一个定义明确且正确的移动构造函数/隐式移动构造函数,那么将项目从 items
移动到 new_items
就与任何其他移动操作相同;容器不会改变这一点。
简而言之,这个责任在于 class,而不是它所使用的容器。
您从中移出的对象处于有效但未指定的状态,并且可以在它们上调用没有前提条件的函数。并且析构函数必须是没有前提条件的函数。如果 SomeType
不满足此条件,则它是错误格式的。
所以不会有双重破坏的问题。