0

The following code compiles in C++17 and does not compile in C++11

class Value
{
public:
    Value() = default;
    ~Value() = default;
    Value(const Value&) = default;
    Value& operator=(const Value&) = default;
    Value(Value&&) = delete;
    Value& operator=(Value&&) = delete;
};
int main()
{
   auto value = Value{};    
}

The message is: error: call to deleted constructor of 'Value' auto value = Value{};
^ ~~~~~~~ note: 'Value' has been explicitly marked deleted here Value(Value&&) = delete;

But if I change to:

int main()
{
    Value value{};    
}

Then it is fine for both C++11 and C++17. Does this have anything to copy elision introduced in C++17?

pidgun
  • 113
  • 6

1 Answers1

1

"Copy elision" itself was not introduced in C++17, it was already present in prior versions of the standard. What allows your code snippet to be compiled in C++17 are the changes in section "11.6 Initializers" (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf):

If the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object. [Example: T x = T(T(T())); calls the T default constructor to initialize x. — end example ]

In your code snippet "Value{}" is a prvalue and it has the same type than the destination object, thus it is directly initialized, without having any copy or move operation involved. This is why that code can be compiled in C++17 but not in C++11.

Only for completeness, the introduced changes were part from this paper: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0135r1.html

AlexCL
  • 412
  • 1
  • 5