Pair trivial move constructor

Christian Rorvik christian.rorvik@gmail.com
Thu Nov 29 11:27:00 GMT 2012


It's my understanding that in GCC 4.7.2 ABI fixes were put in place to
ensure compatibility between code compiled with/without -std=c++11.

As part of that std::pair's move constructor was made trivial, with
its current definition:
constexpr pair(pair&&) = default;


The implication of this appears to be that all types contained in
std::pair must be either movable or trivially copyable, otherwise the
compiler will implicitly delete pair's move constructor and then
complain about its usage. Example:

#include <utility>

struct Foo
{
    Foo();
    Foo(const Foo&);
};

typedef std::pair<Foo, Foo> FooPair;

FooPair create();

void test()
{
    const FooPair x = create();
}


Produces:

a.cpp:15:30: error: use of deleted function 'constexpr std::pair<_T1,
_T2>::pair(std::pair<_T1, _T2>&&) [with _T1 = Foo; _T2 = Foo;
std::pair<_T1, _T2> = std::pair<Foo, Foo>]'
In file included from
/usr/local/gcc-4.7.2/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/utility:72:0,
                 from a.cpp:1:
/usr/local/gcc-4.7.2/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_pair.h:120:17:
note: 'constexpr std::pair<_T1, _T2>::pair(std::pair<_T1, _T2>&&)
[with _T1 = Foo; _T2 = Foo; std::pair<_T1, _T2> = std::pair<Foo,
Foo>]' is implicitly deleted because the default definition would be
ill-formed:
/usr/local/gcc-4.7.2/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_pair.h:120:17:
error: non-static data member 'std::pair<Foo, Foo>::first' does not
have a move constructor or trivial copy constructor
/usr/local/gcc-4.7.2/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../include/c++/4.7.2/bits/stl_pair.h:120:17:
error: non-static data member 'std::pair<Foo, Foo>::second' does not
have a move constructor or trivial copy constructor



I'm not sure how this sits with the standard requirement for
std::pair, but it seems a rather onerous requirement on the user of
pair, and must have massive impact on existing code. If ABI
compatibility requires the move constructor be default generated,
would it make sense to constraint its definition based on whether its
members are move constructible or trivially copyable?


Kind Regards,
Christian Rorvik



More information about the Libstdc++ mailing list