Created on 2025-05-01.00:00:00 last changed 2 months ago
Proposed resolution:
This wording is relative to N5008.
Modify [memory.syn] as indicated:
// 20.4.1, class template indirect template<class T, class Allocator = allocator<T>> class indirect; template<class T, class Allocator> constexpr void swap(indirect<T, Allocator>& lhs, indirect<T, Allocator>& rhs) noexcept(see below); // 20.4.1.10, hash support template<class T, class Alloc> struct hash<indirect<T, Alloc>>; // 20.4.2, class template polymorphic template<class T, class Allocator = allocator<T>> class polymorphic; template<class T, class Allocator> constexpr void swap(polymorphic<T, Allocator>& lhs, polymorphic<T, Allocator>& rhs) noexcept(see below);
Modify [indirect.syn] as indicated:
// 20.4.1.7, swap constexpr void swap(indirect& other) noexcept(see below);friend constexpr void swap(indirect& lhs, indirect& rhs) noexcept(see below);
Modify [indirect.swap] as indicated:
template<class T, class Allocator> constexpr void swap(indirect<T, Allocator>& lhs, indirect<T, Allocator>& rhs) noexcept(noexcept(lhs.swap(rhs)));-3- Effects: Equivalent to `lhs.swap(rhs)`.
Modify [polymorphic.syn] as indicated:
// 20.4.2.7, swap constexpr void swap(polymorphic& other) noexcept(see below);friend constexpr void swap(polymorphic& lhs, polymorphic& rhs) noexcept(see below);
Modify [polymorphic.swap] as indicated:
template<class T, class Allocator> constexpr void swap(polymorphic<T, Allocator>& lhs, polymorphic<T, Allocator>& rhs) noexcept(noexcept(lhs.swap(rhs)));-3- Effects: Equivalent to `lhs.swap(rhs)`.
[ 2025-10-14; Reflector poll ]
Set priority to 2 after reflector poll. Status New → LEWG.
This is a broader issue than just `std::indirect` and `std::polymorphic`, it also affects `std::jthread`, `std::mdspan`, `move_only_function`, `copyable_function`, `node-handle`, `inplace_vector`, `flat_map` and co., and maybe more.
Are we comfortable that defining `swap` as a hidden friend means that the generic `std::swap` might be suboptimal, and for allocator-aware types might even do something with different effects? e.g. if `propagate_on_container_swap` is true but `propagate_on_container_move_assignment` is false.
The non-member `swap` overloads for `std::indirect` and `std::polymorphic` are defined as hidden friends, so are only available via ADL. This means that calling `std::swap(i1, i2)` will always use the generic `std::swap` instead of the custom overload for `std::indirect`.
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2025-10-14 17:45:42 | admin | set | messages: + msg15158 |
| 2025-10-14 17:45:42 | admin | set | status: new -> lewg |
| 2025-05-01 17:37:18 | admin | set | messages: + msg14738 |
| 2025-05-01 00:00:00 | admin | create | |