On 2012-02-16 07:42, GMan wrote:
> For the nicely formatted version of the question with examples, see
> the above link, but to summarize: does std::swap take on the behavior
> of boost::swap in C++11? If not, why?
It does not and the short answer is: If it would do so, it could
silently change the meaning of valid C++03 code. See below for more details.
> In other words, is the following supposed to work in C++11?
>
> #include<utility>
>
> namespace ns
> {
> struct foo
> {
> foo() : i(0) {}
> int i;
>
> private:
> foo(const foo&); // not defined,
> foo& operator=(const foo&); // non-copyable
> };
>
> void swap(foo& lhs, foo& rhs)
> {
> std::swap(lhs.i, rhs.i);
> }
> }
>
> int main()
> {
> ns::foo a, b;
> std::swap(a, b); // finds ns::swap internally, or tries to copy
> (and fails)?
> }
The explicit call of std-qualified swap will only consider the generic
std::swap function (and std::pair's swap overload) which imposes the
MoveConstructible and MoveAssignable requirements. If you want to enable
ADL, you need to replace
std::swap(a, b);
by
using std::swap;
swap(a, b);
This is the way how the swappable requirements are defined in C++11.
> I posted an SO answer showing that it's easily possible in principle,
> yet both MSVC and GCC don't seem to take that route.
The compiler behaviour is conforming.
> (They do follow
> the new mandate that all calls to swap *elsewhere* in the stdlib be
> done without qualification, though. To me this is proof enough that
> the committee could have discussed it.)
The definition of the swappable requirements had been discussed
thoroughly, yes.
> So what I'm looking for is a definite, "yes, GCC and MSVC are wrong
> and here's why", "no, it was brought up and rejected and here's why",
> or, "no, but only because it definitely wasn't brought up." The only
> answer on SO suggests the last of those options, but it's not very
> confident about it. Thanks.
I'm not 100% sure whether this was explicitly discussed, but it was
clear that changing the semantics of valid C++03 code would not be
acceptable.
There was no much time any more to be very inventive, because concepts
had been deferred late in the game (Those would have a similar effect as
the C++11 Swappable requirements now have, only the "using std::swap"
statement could be excluded, because the resolution would find the
concept swap, which again would find ns::foo's free swap). There was a
late idea to provide adl_swap (or consider any other name *except* swap)
which basically encapsulates the lines
using std::swap;
swap(a, b);
but this would just provide a new function, *not* replace the old one.
It was too late for new components, therefore no concrete proposal
provided (It was discussed, though). But there is no fundamental reason,
why such a function should not be added in the future.
HTH & Greetings from Bremen,
Daniel Krügler