std :: adjacent_difference与std :: chrono time_point

无意义

考虑以下代码:

int main()
{
    std::vector<std::chrono::steady_clock::time_point> time;
    time.push_back(std::chrono::steady_clock::now());
    std::this_thread::sleep_for(std::chrono::milliseconds(4));
    time.push_back(std::chrono::steady_clock::now());
    std::this_thread::sleep_for(std::chrono::milliseconds(7));
    time.push_back(std::chrono::steady_clock::now());
    std::vector<std::chrono::duration<double>> diffs;
    std::adjacent_difference(time.begin(),time.end(),std::back_inserter(diffs));
}

它不会编译(有关类型不匹配的丑陋模板错误消息)。当我尝试切换到错误消息(std::chrono::time_point<std::chrono::_V2::steady_clock, std::chrono::duration<long, std::ratio<1, 1000000000>>>)时,错误消息会四处移动。

我的假设是算法不起作用,因为减去2个时间点的结果不是一个时间点,即伪代码中的这行是冲突的。

template<class InputIt, class OutputIt>
constexpr // since C++20
OutputIt adjacent_difference(InputIt first, InputIt last, 
                             OutputIt d_first)
{
    if (first == last) return d_first;
 
    typedef typename std::iterator_traits<InputIt>::value_type value_t;
    value_t acc = *first;  
    *d_first = acc; // <-----------------------------------------------------  1
    while (++first != last) {
        value_t val = *first;
        *++d_first = val - std::move(acc); // std::move since C++20  <-------- 2
        acc = std::move(val);
    }
    return ++d_first;
}

所以我有两个问题:

  1. 我的猜测正确吗?
  2. 最简单的解决方法是什么?我能想到的最好的办法就是从时间点到持续时间的丑陋转变。

尽管chrono是C ++ 11,但由于我对任何C ++ 20解决方案都开放,因此我对C ++ 20进行了标记,尽管我更希望它们不属于range,因为它们未在编译器中实现。

巴里

我的假设是该算法不起作用,因为减去2个时间点的结果不是一个时间点

确实,减去两个time_points不会产生a-time_point它会产生a duration<chrono>duration和中time_point形成仿射空间。这类似于无法添加两个指针的方式,但是可以减去两个指针-得到的不是指针,而是一个ptrdiff_t

adjacent_difference算法不支持此类仿射类型,因为给定范围[a, b, c]指定输出为[a, b-a, c-b]这基本上是行不通的,因为a并且b-a具有不同的,不可转换的类型。

最简单的方法可能是使用range-v3:

zip_with(minus(), time, time | drop(1))

产生您实际想要的相邻差-不包含第一个值(time_point),因此只得到durations的范围


transform()我总是会忘记两个范围的版本(感谢Conor)。这也可行:

std::transform(time.begin(), std::prev(time.end()), std::next(time.begin()),
    std::back_inserter(diffs), std::minus());

这基本上是的“正确”版本adjacent_difference在C ++ 20中,这可能会更清楚一些:

std::ranges::transform(time, time | std::views::drop(1),
    std::back_inserter(diffs), std::minus());

您也可以完全滥用adjacent_find

std::adjacent_find(time.begin(), time.end(), [&](auto t1, auto t2){
    diffs.push_back(t2 - t1);
    return false;
});

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

std :: string到std :: chrono time_point

std :: string中的std :: chrono :: time_point

std :: chrono :: time_point线程安全吗?

无法在std :: chrono :: time_point之间转换

如何获取std :: chrono :: time_point时钟类型

将boost :: chrono :: steady_clock :: time_point转换为std :: chrono :: steady_clock :: time_point

从std :: chrono :: time_point转换后,C ++ std :: tm返回错误的值

为什么不能默认构造std :: chrono time_point成员变量的std :: atomic?

与 std::numeric_limits::infinity() 等效的 std::chrono::time_point 是什么?

std :: atomic <std :: chrono :: high_resolution_clock :: time_point>无法编译

如何在 C++ 中将 Windows FILETIME 转换为 std::chrono::time_point<std::chrono::file_clock>

二进制'> =':'std :: chrono :: system_clock :: time_point'

从编译时已知的日历日期创建`std :: chrono :: time_point`

错误:从std :: chrono :: time_point浮点数转换为非标量类型long int

C ++如何将std :: chrono :: time_point转换为long并返回

将std :: chrono :: system_clock :: time_point转换为struct timeval并返回

持久性 std::chrono time_point<steady_clock>

为什么std :: chrono :: time_point的大小不足以存储struct timespec?

用std :: chrono :: time_point隐式删除特殊功能

如何将std :: chrono :: time_point转换为字符串

两个std :: chrono :: time_point之间的operator =导致错误

从变量转换时std :: chrono :: time_point编译器错误

比较两个std :: chrono :: time_point实例时出错

如何从std :: chrono :: system_clock :: time_point.time_since_epoch()。count()中获取std :: chrono :: system_clock :: time_point?

std :: time_point往返于std :: string

试图从time_point(C ++)中减去std :: chrono :: duration,但我的代码未编译。有什么建议?

Apple Clang:为什么我不能从std :: chrono :: nanoseconds创建一个time_point

如何为1970年1月1日00:00:00创建std :: chrono :: time_point?

如何将YYYY / MM / DD HH:MM:SS转换为std :: chrono :: system_clock :: time_point?