【发布时间】:2021-09-06 16:29:25
【问题描述】:
标准中有四种pair-like类型,分别是std::array、std::pair、std::tuple和ranges::subrange,其中std::get对ranges::subrange的重载在[range.subrange#access-10]中定义:
template<size_t N, class I, class S, subrange_kind K> requires (N < 2) constexpr auto get(const subrange<I, S, K>& r); template<size_t N, class I, class S, subrange_kind K> requires (N < 2) constexpr auto get(subrange<I, S, K>&& r);效果:相当于:
if constexpr (N == 0) return r.begin(); else return r.end();
而ranges::subrange::begin() 有两个重载:
constexpr I begin() const requires copyable<I>;
[[nodiscard]] constexpr I begin() requires (!copyable<I>);
我注意到这个std::get只有两个重载,并且非常量左值引用没有对应的重载,这使得我们无法将std::get应用于左值@987654336 @ 与非copyable 迭代器(godbolt):
#include <ranges>
#include <sstream>
int main() {
auto ints = std::istringstream{"42"};
auto is = std::ranges::istream_view<int>(ints);
std::ranges::input_range auto r = std::ranges::subrange(is);
auto b = r.begin(); // OK
auto b2 = std::get<0>(r); // Error, passing 'const subrange' as 'this' argument discards qualifiers
}
那么为什么std::get 对于ranges::subrange 只有两个函数重载?它会错过ranges::subrange& 和const ranges::subrange&& 的重载吗?这是标准缺陷还是故意的?
【问题讨论】:
标签: c++ c++20 std-ranges