https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100824
Bug ID: 100824 Summary: ranges::size should treat the subexpression as an lvalue Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: hewillk at gmail dot com Target Milestone: --- The CPO described in [range.access] treats the subexpression E as an lvalue, but ranges::size, ranges::empty, and ranges::data forward E perfectly, which makes the following case behavior wrong: https://godbolt.org/z/7KoT3WE41 #include <ranges> #include <array> struct R : std::ranges::view_base { constexpr int* begin() & { return nullptr; } constexpr int* end() & { return nullptr; } constexpr int size() & { return 42; } }; template <> inline constexpr bool std::ranges::enable_borrowed_range<R> = true; // call ranges::end(e) - ranges::begin(e) incorrectly static_assert(std::ranges::size(R{})); int main() { std::array r{42, 42, 42}; // call e.data() correctly (r | std::views::all).data(); // call std::to_address(ranges::begin(e)) incorrectly std::ranges::data(r | std::views::all); }