Range-v3,如何单独访问范围值的范围(group_by 函数)

Range-v3, how to access a range of a range value individually (group_by function)

我正在使用 Eric Niebler 的 range-v3 并使用 ranges::views::group_by 函数。

documentation for group_by 中它说:“给定源范围和二进制谓词,return 范围范围,其中每个范围包含源范围中的连续元素使得以下条件成立:对于范围内除第一个元素之外的每个元素,当该元素和第一个元素传递给二元谓词时,结果为真。本质上,views::group_by 将连续元素组合在一起一个二元谓词。

因此,它 return 是一个范围和范围。我的问题是如何单独访问范围的范围?我已经尝试了所有访问范围的使用方法:p[0].first、p.at(0).first、p.begin.first 等,但没有快乐。

我有以下代码:

#include "https://raw.githubusercontent.com/HowardHinnant/date/master/include/date/date.h"
#include <chrono>
#include <fmt/format.h>
#include <iostream>
#include <map>
#include <range/v3/all.hpp>

using namespace date;

template <typename TimePoint, typename Minutes>
constexpr auto candle_start(const TimePoint timestamp, const Minutes timeframe)
    -> TimePoint {
  using namespace std::chrono;

  const auto time =
      hh_mm_ss{floor<minutes>(timestamp - floor<days>(timestamp))};
  return timestamp - (time.minutes() % timeframe);
}

auto main() -> int {
  {
    using namespace std::chrono;
    using namespace std::chrono_literals;

    const auto tp_now = std::chrono::system_clock::from_time_t(0);

    const auto m =
        std::map<system_clock::time_point, double>{{tp_now + 0min, 1.1},
                                                   {tp_now + 1min, 2.2},
                                                   {tp_now + 2min, 3.3},
                                                   {tp_now + 3min, 4.4},
                                                   {tp_now + 4min, 5.5},
                                                   {tp_now + 5min, 6.6},
                                                   {tp_now + 6min, 7.7},
                                                   {tp_now + 7min, 8.8},
                                                   {tp_now + 8min, 9.9},
                                                   {tp_now + 9min, 10.10},
                                                   {tp_now + 10min, 11.11},
                                                   {tp_now + 11min, 12.12},
                                                   {tp_now + 12min, 13.13},
                                                   {tp_now + 13min, 14.14}};
  
  const auto timeframe = 2min;

  const auto same_candle = [timeframe](const auto &lhs, const auto &rhs) {
    return candle_start(lhs.first, timeframe) ==
           candle_start(rhs.first, timeframe);
  };

  auto p = m
    | ranges::views::reverse 
    | ranges::views::group_by(same_candle);

    // How do I access the range of range values individually?
    std::cout << p[0].first << " = " << p[0].second;

    return 0;
  }

并给出了一个游乐区here

p 不是随机访问范围(不可能),因此不会支持索引(即 [0])。然后 p 不是一对的范围,它是 范围的 对的范围。

所有视图都有一个从 view_interface 继承的 front() 成员函数,所以如果你想打印第一个子范围的 firstsecond 成员第一个范围,你可以这样做:

std::cout << p.front().front().first << " = " << p.front().front().second;

或者您可以像往常一样使用迭代器。

fmt 还支持格式化整个范围,因此如果您只想调试,这可能是您最好的选择:

fmt::print("{}\n", p);

您需要包含 fmt/ranges.h 以获得此支持,并包含 fmt/chrono.h 用于特定于时间的格式化程序。