2

This is not intended to be a duplicate of What is a proper way to implement is_swappable to test for the Swappable concept? especially regarding the aspect "testing for the Swappable concept".

I tried to implement a trait is_std_swappable:

#include <type_traits>
#include <utility>

template< typename T, typename = void >
struct is_std_swappable : std::false_type {};

template< typename T >
struct is_std_swappable< T, decltype( std::swap( std::declval< T& >(), std::declval< T& >() ) ) > : std::true_type {};

This works for a std::string and static_assert( is_std_swappable< std::string >::value, "" ); does not error.

Now I tried a type that should not be swappable by std::swap assuming an implementation using std::move:

struct DontMove {
    DontMove() = default;
    DontMove( DontMove&& ) = delete;
};

static_assert( is_std_swappable< DontMove >::value, "" );

Result (see https://godbolt.org/z/014kJ2):

  • Clang 7.0.0 sees an error here ("static_assert failed due to requirement is_std_swappable<DontMove>::value").

  • MSVC 19.16 does not error. That might happen if MSVC provides a non-moving implementation of std::swap. On the other hand, using the swap yields an error ("attempting to reference a deleted function"):

    void foo() {
        DontMove dm;
        std::swap( dm, dm );
    }
    

Who's right here? Or is my try on the is_std_swappable faulty?

mkluwe
  • 3,823
  • 2
  • 28
  • 45
  • 1
    The reason this fails is explained in [this answer](https://stackoverflow.com/a/26744937/4342498) on the dupe. I used it as a dupe as it has workarounds offered as well – NathanOliver Feb 19 '19 at 17:13
  • It's not clear that this "fails". The compilers behave differently here. I tried to reproduce the other solution in https://godbolt.org/z/NQajmI. Same result. So this possibly is not a duplicate of [the other question](https://stackoverflow.com/questions/26744589/what-is-a-proper-way-to-implement-is-swappable-to-test-for-the-swappable-concept). – mkluwe Feb 19 '19 at 17:25
  • Ah, I see. I wanted "Instantion failure is not an error" instead of SFINAE. – mkluwe Feb 19 '19 at 19:23

1 Answers1

1

The standard does not require std::swap to be SFINAE-friendly. Neither does it prevent it.

Neither compiler is wrong.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • I had to learn about SFINAE-friendliness first. Now I will have to look for the implementation of `std::swap` in libc++. – mkluwe Feb 19 '19 at 19:26