I try to apply boost::range::conbine
to a couple of std::subrange
s but the example does not compile.
#include <array>
#include <ranges>
#include <boost/range/combine.hpp>
#include <iostream>
int main() {
auto arr = std::array{1, 2, 3, 4, 5};
auto firsts = std::ranges::subrange(arr.begin(), arr.end() - 1);
auto seconds = std::ranges::subrange(arr.begin() + 1, arr.end());
for (auto [f, s]: boost::range::combine(arr, arr)) {
std::cout << f << " " << s << std::endl;
}
/*
// Does not compile.
for (auto [f, s]: boost::range::combine(firsts, seconds)) {
std::cout << f << " " << s << std::endl;
}
*/
return 0;
}
What is the reason for boost not to support subrange? Or is it a bug?
The subrange models a
view
, and in this particular case alsosized_range
. Neither of these satisfycombine
's required Range ConceptSinglePassRange
.The compiler tells you as much:
Using Boosts model instead
So you can use the Boost range model:
Live On Compiler Explorer
Printing
Use
std::views::zip
insteadIf you have a compiler that implements c++23 library supports already, you can use
std::views::zip
Use RangeV3 library instead
This implementation contains things not (yet) standardized, and also supports
zip
Extend Boost Range
You can make Boost recognize
std::ranges::subrange
. I think Method 2: Provide Free-standing Functions And Traits is probably appropriate. The absolute bare minimum allows it to work:Live On Compiler Explorer
Printing
Summary/Notes
The above subtly assumes sized subranges (K is
subrange_kind::sized
), by requiring the sentinel is just an iterator. This is not very accurate (see e.g.sized_sentinel_for
) but it was the simplest thing to do for the purpose of teaching Boost how to use the subranges from your question.