使用std :: remove_if()

时间:2018-07-10 22:28:15

标签: c++ templates compiler-errors

我正在尝试编写一个随时间推移的滑动窗口,并删除最旧的数据作为模板类。我使用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没有可行的“ operator =”。 我使用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));

您能解释问题出在哪里吗?谢谢。

1 个答案:

答案 0 :(得分:4)

remove_if通过赋值工作,并且不适用于地图(或集合),因为其键为const 1 。 (它实际上也没有从容器中删除元素,因此没有删除删除习惯用法。)

LFTS v2为此具有erase_if。链接的页面还显示了您可以使用的实现。

此外,由于map将其元素保持在已排序的顺序,因此最好先进行搜索(使用lower_bound),然后再进行范围擦除。假设Timemilliseconds的精度更高,因此now - ms可转换为Time

auto x = mData.lower_bound(now - ms);
mData.erase(mData.begin(), x);

1 从技术上讲,它不是const的集合,而集合仅提供const对元素的访问。