What is, from the point of view of the C ++ standard, the expected (if any) output of the following program:
#include <iostream>
In other words, does the attribute value only evaluate the declaration of the assignment operator, which is no exception, and thus it gives
true true
Or it considers the call context ( a , b are instances of a )
a = b; // may throw, implicitly calls copy c'tor a = std::move(b); // noexcept, implicitly calls move c'tor
and does he give
false true
Practical attempts
Running code with Visual Studio 2015, Update 3 gives
true true
whereas gcc 6.1 gives
false true
Who is right?
Background
A similar situation occurs when we have a resource management class using the metadata of the copy constructor (since resource allocation may fail), the express-free constructor, metadata assignment, and non-capturing assignment.
Suppose that both copying and moving can be effectively implemented from the point of view of idom exchange:
A& operator=(A const& other) { A(other).swap(*this);
Then we could consider the possibility of condensation as a single copy assignment by default
A& operator=(A other) noexcept { other.swap(*this); return *this; }
However, we can only do this safely if std::is_nothrow_copy_assignable<A> and std::is_nothrow_move_assignable<A> provide the correct values (false and true, respectively). Otherwise, code based on these types will behave badly, and our single value assignment will not be a suitable replacement for two separate assignment operators.