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()
成员函数,所以如果你想打印第一个子范围的 first
和 second
成员第一个范围,你可以这样做:
std::cout << p.front().front().first << " = " << p.front().front().second;
或者您可以像往常一样使用迭代器。
fmt
还支持格式化整个范围,因此如果您只想调试,这可能是您最好的选择:
fmt::print("{}\n", p);
您需要包含 fmt/ranges.h
以获得此支持,并包含 fmt/chrono.h
用于特定于时间的格式化程序。
我正在使用 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()
成员函数,所以如果你想打印第一个子范围的 first
和 second
成员第一个范围,你可以这样做:
std::cout << p.front().front().first << " = " << p.front().front().second;
或者您可以像往常一样使用迭代器。
fmt
还支持格式化整个范围,因此如果您只想调试,这可能是您最好的选择:
fmt::print("{}\n", p);
您需要包含 fmt/ranges.h
以获得此支持,并包含 fmt/chrono.h
用于特定于时间的格式化程序。