This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

4250. swap overloads for indirect and polymorphic only found by ADL

Section: 20.4.1.7 [indirect.swap], 20.4.2.7 [polymorphic.swap] Status: New Submitter: Jonathan Wakely Opened: 2025-05-01 Last modified: 2025-05-01

Priority: Not Prioritized

View all issues with New status.

Discussion:

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.

Proposed resolution:

This wording is relative to N5008.

  1. Modify 20.2.2 [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);
    
    
  2. Modify 20.4.1.2 [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);
    
  3. Modify 20.4.1.7 [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).
  4. Modify 20.4.2.2 [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);
    
  5. Modify 20.4.2.7 [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).