Consider the following code:
#include <iostream>
struct Thing
{
Thing(void) {std::cout << __PRETTY_FUNCTION__ << std::endl;}
Thing(Thing const &) = delete;
Thing(Thing &&) = delete;
Thing & operator =(Thing const &) = delete;
Thing & operator =(Thing &&) = delete;
};
int main()
{
Thing thing{Thing{}};
}
I expect Thing thing{Thing{}};
statement to mean construction of temporary object of Thing
class using default constructor and construction of thing
object of Thing
class using move constructor with just created temporary object as an argument. And I expect that this program to be considered ill-formed because it contains an invocation of deleted move constructor, even though it can be potentially elided. The class.copy.elision section of standard seems to demand this as well:
the selected constructor must be accessible even if the call is elided
The Wording for guaranteed copy elision through simplified value categories does not seem to allow it either.
However gcc 7.2 (and clang 4 as well, but not VS2017 which still does not support guaranteed copy elision) will compile this code just fine eliding move constructor call.
Which behavior would be correct in this case?