jeudi 3 mars 2016

std::swap causes infinite recursion in VS 2013

Consider this snippet:

#include <utility>

struct foo
{
    foo()
    {
    }

    foo(foo&& other)
    {
        std::swap(*this, other);
    }
};

int main(int argc, char** argv)
{
    foo f(std::move(foo()));
}

It causes infinite recursion in VS2013, but fails to compile with g++/clang with errors that operator= is deleted (which makes sense):

In file included from /usr/local/include/c++/5.3.0/bits/stl_pair.h:59:0,
                 from /usr/local/include/c++/5.3.0/utility:70,
                 from main.cpp:1:
/usr/local/include/c++/5.3.0/bits/move.h: In instantiation of 'void std::swap(_Tp&, _Tp&) [with _Tp = foo]':
main.cpp:11:26:   required from here
/usr/local/include/c++/5.3.0/bits/move.h:186:11: error: use of deleted function 'foo& foo::operator=(const foo&)'
       __a = _GLIBCXX_MOVE(__b);
           ^
main.cpp:3:12: note: 'foo& foo::operator=(const foo&)' is implicitly declared as deleted because 'foo' declares a move constructor or move assignment operator
     struct foo
            ^
In file included from /usr/local/include/c++/5.3.0/bits/stl_pair.h:59:0,
                 from /usr/local/include/c++/5.3.0/utility:70,
                 from main.cpp:1:
/usr/local/include/c++/5.3.0/bits/move.h:187:11: error: use of deleted function 'foo& foo::operator=(const foo&)'
       __b = _GLIBCXX_MOVE(__tmp);
           ^

I assume this is a VS bug. But does the standard impose any rules on how std::swap should be implemented? I mean is this simply a bad implementation in VS or a violation of the standard?

Aucun commentaire:

Enregistrer un commentaire