如何为std::list重载std::remove
How to overload std::remove for std::list?
我曾经了解到,从容器中擦除元素的一般方法是通过擦除-移除习惯用法。但我惊讶地发现,至少g++的STL实现不会为std::list重载std::remove((,因为在这种情况下,通过指针操作进行重新排序可以保存许多对象分配。
C++标准不要求进行这样的优化是有原因的吗?但我的主要问题是如何重载std::remove(((它不必在g++之外可移植(,因此我可以提供一个使用list::splice((/list::merge((的实现。我尝试了几个签名,但最多只能得到一个模糊性错误,例如:
template <typename T>
typename std::list<T>::iterator
remove(typename std::list<T>::iterator first,
typename std::list<T>::iterator last, const T &v);
附言:很抱歉我不够清楚。请忽略这些函数来自std命名空间以及它们的具体作用。我只是想了解更多关于C++中的模板/类型特征/重载规则的信息。
它不是强制性的,因为它不仅仅是一个优化,它的语义与您对序列容器的期望不同:
std::list<int> l;
l.push_back(1);
l.push_back(2);
std::list<int>::iterator one = l.begin();
std::list<int>::iterator two = l.end(); --two;
if (something) {
l.erase(remove(l.begin(), l.end(), 1), l.end());
// one is still valid and *one == 2, two has been invalidated
} else {
l.remove(1);
// two is still valid and *two == 2, one has been invalidated
}
关于实际的问题:ISWYM,我暂时不知道如何编写一对函数模板,以便一个匹配任意迭代器,另一个匹配列表迭代器。
请注意,标准中实际上并不能保证list<T>::iterator
与some_other_container<T>::iterator
是不同的类型。因此,尽管在实践中,您希望每个容器都有自己的迭代器,但原则上,除了建议将重载放在std
中之外,这种方法是有缺陷的。不能单独使用迭代器对其相应的容器进行"结构"更改。
你可以毫不含糊地做到这一点:
template <typename Container>
void erase_all(Container &, const typename Container::value_type &);
template <typename T>
void erase_all(std::list<T> &, const T &);
list::remove
或list::erase
单独使用将完成您所看到的擦除/移除习惯用法对向量所做的操作。
值或谓词的remove
。erase
用于单个迭代器或范围。
您收到的建议很好,但并不普遍。例如,这对std::vector
有好处,但对std::list
来说完全没有必要,因为std::list::erase()
和std::list::remove()
已经做了正确的事情。它们可以实现您请求的所有指针魔术,而std::vector::erase()
无法做到这一点,因为它的内部存储不同。这就是std::remove()
不专门用于std::list
的原因:因为在这种情况下不需要使用它。
- <T> 通过模板化运算符重载将 std::complex 乘以双倍
- std::vector 没有重载函数的实例与参数列表匹配
- 在缺少函数重载时抛出异常,并带有 std::variant 而不是编译时错误
- 重载 + 自己的类和 std::string 的运算符
- 使用重载 [] 运算符返回 std::map() 的可赋值
- VSCode 说 std::chrono 是模棱两可的,如果运算符<<重载
- 重载 std::字符串运算符+ 用于打印枚举名称
- 具有std::initializer_list参数的非成员函数(/non构造函数上下文)的重载解析
- C++派生类重载函数(带有 std::function 参数)不可见
- 为什么 std::sort 找不到合适的(静态成员)函数重载?
- 使用 MINGW gcc 编译时,不会为 std::string 调用重载的新运算符
- 尝试使用谓词函数会导致错误:"std::sort"未找到匹配的重载函数
- std::调用,未找到匹配的重载函数
- C++:使用 std::unique_ptr 访问重载运算符++的最佳方式?
- C++:从重载函数转换为 std::function
- msvc 编译器(和其他编译器)如何知道要绑定到哪个 std 重载?
- 关于在成员重载中使用 std::move() 的问题
- 将模板(没有规范)传递给 std::thread() 会出现错误:<未解析的重载函数类型>匹配错误
- 在 std::visit 中跳过变体类型的一些重载组合的方法是什么?
- std::begin-类型特征中未考虑用户定义的重载