【问题标题】:No viable overloaded '=' when using std::remove_if()使用 std::remove_if() 时没有可行的重载 '='
【发布时间】:2018-07-10 22:28:15
【问题描述】:

我正在尝试编写一个随时间滑动的滑动窗口,并将最旧的数据作为模板类删除。我使用 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));

你能解释一下问题出在哪里吗?谢谢。

【问题讨论】:

    标签: c++ templates compiler-errors


    【解决方案1】:

    remove_if 通过赋值起作用,它不适用于地图(或集合),因为它们的键是 const1。 (它实际上也不会从容器中删除元素,因此使用了erase-remove 习惯用法。)

    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对其元素的访问。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-15
      • 1970-01-01
      • 1970-01-01
      • 2011-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多