mardi 19 février 2019

Corrent implementation of is_std_swappable

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?

Aucun commentaire:

Enregistrer un commentaire