Open
Description
The has-tuple-element
exposition-only concept (used for std::ranges::elements_view
) was modified by P2165R4 in C++23. Previously, the constraints were more relaxed.
As a result, the following program should be well-formed in C++20 but ill-formed in C++23.
#include <cstddef>
#include <ranges>
#include <utility>
#include <type_traits>
template<class T, class U>
struct MyPair : std::pair<T, U> { // std::get works with MyPair specializations.
using std::pair<T, U>::pair;
};
template<class T, class U>
struct std::tuple_size<MyPair<T, U>> : std::integral_constant<std::size_t, 2> {};
template<class T, class U>
struct std::tuple_element<0, MyPair<T, U>> {
using type = T;
};
template<class T, class U>
struct std::tuple_element<1, MyPair<T, U>> {
using type = U;
};
int main() {
MyPair<int, double> mps[42]{};
(void)(mps | std::views::elements<0>);
}
Currently, libstdc++ and MSVC STL accept it in C++20 and reject it in C++23 as specified by the standard, but libc++ rejects it in C++20 (Godbolt link).
This might be intended, as the commit adding elements_view
(9446182, https://reviews.llvm.org/D136268) used the C++23 rules in the first place. I wonder whether we should use the old rules in C++20 mode.
CC @huixie90