c++ - 使用 std::remove_if() 时没有可行的重载 '='
问题描述
我正在尝试编写一个随时间滑动的滑动窗口,并将最旧的数据作为模板类删除。我使用 std::map 作为容器和 std::chrono 来操纵时间。我在负责删除早于 X 毫秒的数据的方法中出现编译时错误:
include/c++/5.4.0/bits/stl_pair.h:170:8: error: no viable overloaded '='
first = std::forward<first_type>(__p.first);
我不明白为什么std::chrono::steady_clock::time_point
没有可行的“运算符=”。我使用 clang++ 编译器。
这是模板代码:
#include <algorithm>
#include <chrono>
#include <map>
#include <utility>
template <class Data, class Clock, class Time = typename Clock::time_point>
class TimeSlideWindow {
private:
std::map<Time, Data> mData;
public:
void insert(Data value)
{
mData.insert(std::make_pair(Clock::now(), value));
}
void clearOlderThan(std::chrono::milliseconds ms)
{
Time now = Clock::now();
remove_if(mData.begin(),
mData.end(),
[ms, now](const std::pair<Time, Data> &elem) {
return elem.first < (now - ms);
});
}
};
这里是模板实例化:
TimeSlideWindow<unsigned long, std::chrono::steady_clock> window;
window.clearOlderThan(std::chrono::milliseconds(3));
你能解释一下问题出在哪里吗?谢谢你。
解决方案
remove_if
通过分配工作,它不适用于地图(或集合),因为它们的键是const
1。(它实际上也不会从容器中删除元素,因此是擦除删除习惯用法。)
LFTS v2 就是erase_if
为了这个目的。链接页面还显示了您可以使用的实现。
此外,由于map
保持其元素排序,您最好先进行搜索 (with lower_bound
),然后进行范围擦除。假设它Time
具有更高的精度,milliseconds
因此now - ms
可以转换为Time
:
auto x = mData.lower_bound(now - ms);
mData.erase(mData.begin(), x);
1从技术上讲,它不适const
用于集合,但集合仅提供const
对其元素的访问。
推荐阅读
- javascript - 在 Javascript 中使用按钮显示和隐藏元素
- android - Firebase 存储错误:参数无效:“_File”实例
- java - 处理从文件读取的值时的最佳实践
- r - 如何使用 dplyr lag() 平滑变量中的微小变化
- c++ - C6001 关于使用未初始化值的地址。为什么?
- java - Android Java Firebase runTransaction 在类不完全相同时删除值
- java - “对象='用户'的验证失败。错误计数:1”而不是“电子邮件不能为空”
- java - 对来自 Firestore 的旧数据的新数据进行分页
- python - 在 sklearn 管道中转换估计器的结果
- c# - 动态生成表单的 Dotnet 核心 MVC 服务器端验证