Date: Thu, 29 Oct 2026 08:16:16 +0800
Link: https://godbolt.org/z/Yd6j6WzrE
The idea is that current 'std::common_reference_with<T, U>' is unlike
'std::same_as<T, U>' such that it's not commutative.
One little change on the definition of the concept
'std::common_reference_with<T, U>' can make it commutative.
The code below proves that:
```
#include <concepts>
// Turn this 1 to 0 and see what happens, then turn it back to 1 to get
the idea.
#if 1
template <class T, class U>
concept common_reference_with =
std::same_as<std::common_reference_t<T, U>,
std::common_reference_t<U, T>> &&
std::convertible_to<T, std::common_reference_t<T, U>> &&
std::convertible_to<U, std::common_reference_t<U, T>>; // Note
here, the current standard is `common_reference_t<T, U>`.
#else
using std::common_reference_with;
#endif
template <class T, class U> requires common_reference_with<T, U>
void f();
template <class T, class U> requires common_reference_with<U, T> && true
[[deprecated("Right.")]] void f();
int main()
{
f<int&, const int&&>();
}
```
The idea is that current 'std::common_reference_with<T, U>' is unlike
'std::same_as<T, U>' such that it's not commutative.
One little change on the definition of the concept
'std::common_reference_with<T, U>' can make it commutative.
The code below proves that:
```
#include <concepts>
// Turn this 1 to 0 and see what happens, then turn it back to 1 to get
the idea.
#if 1
template <class T, class U>
concept common_reference_with =
std::same_as<std::common_reference_t<T, U>,
std::common_reference_t<U, T>> &&
std::convertible_to<T, std::common_reference_t<T, U>> &&
std::convertible_to<U, std::common_reference_t<U, T>>; // Note
here, the current standard is `common_reference_t<T, U>`.
#else
using std::common_reference_with;
#endif
template <class T, class U> requires common_reference_with<T, U>
void f();
template <class T, class U> requires common_reference_with<U, T> && true
[[deprecated("Right.")]] void f();
int main()
{
f<int&, const int&&>();
}
```
Received on 2026-10-29 00:16:27
