Issue 52952
Summary std::ranges::cbegin falls back to lvalue behavior for a non-borrowed rvalue argument
Labels bug, libc++
Assignees
Reporter CaseyCarter
    Per [range.access.cbegin]/1.2, for an rvalue argument `E` of type `T`, `std::ranges::cbegin(E)` is _expression_-equivalent to `std::ranges::begin(static_cast<const T&&>(E))`. In this program:
```c++
#include <ranges>
#include <utility>

struct BeginMember {
  int x;
  constexpr const int *begin() const { return &x; }
};

int main() {
  const BeginMember r{};
  (void) std::ranges::cbegin(std::move(r)); // Should error and does not
  (void) std::ranges::begin(std::move(r)); // Should error and does
}
```
`E` is `std::move(r)`, and `T` is `const BeginMember`, but `std::ranges::cbegin(E)` (accepted) is not _expression_-equivalent to `std::ranges::begin(static_cast<const T&&>(E))` (rejected). It seems that the `cbegin` call with a `const` rvalue argument is binding to a `const` lvalue overload.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to