关于std::is_swappable_with_v判断结果与实际swap调用不一致的技术问询
std::is_swappable_with_v for Valid Swap Call: Is This a Bug? Great question—this inconsistency between compiler behavior is definitely confusing, especially since cppreference explicitly states that a valid swap call (after using std::swap;) should correspond to is_swappable_with<T,U>::value being true.
Let’s break down what’s happening here:
1. Standard Definition of std::is_swappable_with
Per the C++ standard, std::is_swappable_with<T, U> evaluates to true if and only if:
- The expressions
swap(t, u)andswap(u, t)are well-formed, wheretis an lvalue of typeTanduis an lvalue of typeU. - The lookup for
swapin this context includesstd::swap(via an implicitusing std::swap;equivalent) plus any overloads found via Argument-Dependent Lookup (ADL) for the typesTandU.
2. Why Your swap Call is Valid
Your global swap template:
template <class T, class U> constexpr void swap(A<T>&, A<U>&) {}
is a perfect match for swap(A<int>&, A<double>&) (and vice versa). When you call swap(a,b) with lvalues a and b, ADL finds this template in the global namespace (since A<T> is defined there), so all compilers accept it without issue.
3. Why GCC/Clang Reject the static_assert
This appears to be an implementation bug in GCC and Clang. Their is_swappable_with checks are failing to properly resolve the ADL lookup for your templated swap function when verifying cross-type A<T>/A<U> swaps.
The critical point here is cppreference’s explicit guarantee: if the actual swap call compiles successfully, is_swappable_with_v should return true. MSVC’s acceptance of the static_assert aligns with this guarantee, while GCC/Clang’s rejection does not.
You can confirm this is a template-specific bug by testing a non-templated swap overload (e.g., void swap(A<int>&, A<double>&)): GCC/Clang will correctly accept the static_assert in that case, proving the issue lies in how their is_swappable_with implementation handles templated cross-type swap overloads.
Conclusion
Yes, GCC and Clang are incorrect to reject the static_assert here. This deviates from the standard’s requirements and cppreference’s documented behavior. You can report this as a bug to the respective compiler teams if you wish.
内容的提问来源于stack exchange,提问作者463035818_is_not_an_ai

