STL "erase-remove"成语:为什么不"resize-remove"?
STL "erase-remove" idiom: Why not "resize-remove"?
的理解是从std::vector
中完全删除所需项目的好方法是擦除-删除习惯用语。
如上面的链接(截至本文发布之日)中所述,在代码中,擦除删除习惯用语如下所示:
int main()
{
// initialises a vector that holds the numbers from 0-9.
std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// erase-remove idiom to completely eliminate the desired items from the vector
v.erase( std::remove( std::begin(v), std::end(v), 5 ), std::end(v) );
}
我想知道resize-remove
成语在功能和性能方面是否等同于erase-remove
成语。 或者,也许我错过了一些明显的东西?
以下resize-remove
成语等同于上述erase-remove
成语吗?
int main()
{
std::vector<int> v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
// Is this "resize-remove" approach equivalent to the "erase-remove" idiom?
v.resize( std::remove( std::begin(v), std::end(v), 5 ) - v.begin() );
}
在我看来,有两个原因:
-
std::remove
算法只需要前向迭代器,但-
操作需要随机访问迭代器。 -
std::remove
的结果意味着"容器的新终结"。从逻辑上讲,我们应该抹去["容器的新端","容器的旧端")。
它等效于 std::vector,但不适用于 std::list 或其他容器。不确定 std::list 是否可以减去迭代器,即使可以,这也是一个 O(N) 操作。
它应该没有任何区别; resize
的定义是用的insert
和erase
.但通常最好使用标准成语,以便于识别。 和的当然,擦除删除成语适用于任何序列容器,而不仅仅是那些支持 resize
. (全部标准容器似乎确实支持resize
,但它似乎不是必需的。 所以它可能不可用在用户定义的容器上,即使它们支持所有必需的操作。
在性能方面:resize
必须额外执行一项操作测试,以确定它是擦除还是插入,但是我无法想象这会产生重大影响。
我认为erase(first,last)
中的erase
保证first
之前的任何元素都不会被访问或修改,而resize
只有在由于调整大小而没有发生重新分配时才保证这一点。
编辑:正如其他人指出的那样,这样的重新分配永远不会发生,所以没有区别
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 警告处理为错误这里有什么问题
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 为"adjacent"变量赋值时出现问题
- C++为构建时间获取QDateTime的可靠方法
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 努力将整数转换为链表。不知道我在这里做错了什么
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 为char数组调整zlib-zpipe
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- vector.resize()中的分配错误
- 将 opencv 从 2.4.13 转换为 3.3.1 时由 cv::resize() 引起的运行错误
- 为二进制树编码remove()函数
- 将vector::resize()的大小调整为较低计数时重新分配的空间
- 如何为std::vector设置有效的.begin()和.end()而不使用.resize()
- 将src和dst-img设置为与opencv resize函数相同
- 如何为std::list重载std::remove
- STL "erase-remove"成语:为什么不"resize-remove"?