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).