This code fails to compile with gcc 4.8.2 (-std=c++11) but compiles with clang 3.4 (trunk) (-std=c++11):
#include <type_traits>
#include <vector>
struct X {
X& operator=(X&&) noexcept = default;
// adding noexcept this leads to an error in gcc, but works in clang:
// function ‘X& X::operator=(X&&)’ defaulted on its first
// declaration with an exception-specification that differs from the
// implicit declaration ‘X& X::operator=(X&&)’
std::vector<char> m;
};
// this assert holds, even without noexcept
static_assert(std::is_nothrow_move_assignable<X>::value,
"type-specification violation");
int main()
{
return 0;
}
The static_assert is the interesting part on gcc: the defaulted move assignment will be noexcept, but I cannot declare it that way.
A variant not involving vector is:
template<bool b>
struct F {
F& operator=(F&&) noexcept(b) {return *this;}
};
struct X {
X& operator=(X&&) noexcept = default;
F<true> f;
};
What is the expected behavior here? Intuitively clang seems correct.