0

I expect the following code to result in an error, regardless of whether the copy is optimized or not:

struct A {
    A() {}
    A(const A&) = delete;
};

int main() {
    A a = A();
}

Indeed, this is what happens in C++14 and earlier:

main2.cpp:7:7: error: call to deleted constructor of 'A'
    A a = A();
      ^   ~~~
main2.cpp:3:5: note: 'A' has been explicitly marked deleted here
    A(const A&) = delete;
    ^

But in C++17, this peacefully compiles (with both gcc and clang). What change in C++17 is responsible for this, and how can I now enforce the previous semantics?

Simeon
  • 143
  • 2
  • 4
  • 3
    `A a = A();` is copy initialisation __since C++17__ and is done in-place no temporary is created. _"...First, if T is a class type and the initializer is a prvalue expression whose cv-unqualified type is the same class as T, the initializer expression itself, rather than a temporary materialized from it, is used to initialize the destination object: see copy elision..."_ https://en.cppreference.com/w/cpp/language/copy_initialization Also read the C++17 section here - [Mandatory elision of copy/move operations](https://en.cppreference.com/w/cpp/language/copy_elision) – Richard Critten Nov 28 '21 at 18:40
  • @RichardCritten The semantics of it might have changed in C++17, but haven't `A a = A();` *always* been copy-initialization? – Some programmer dude Nov 28 '21 at 18:58
  • @RichardCritten And if the copy-constructor is explicitly deleted, shouldn't it disallow any kind of copying, elision or not? – Some programmer dude Nov 28 '21 at 19:00
  • 1
    @Someprogrammerdude _"...The copy/move constructors need not be present or accessible:..._ https://en.cppreference.com/w/cpp/language/copy_elision [re: _"...The semantics of it might..."_ yes I put the _and_ in the wrong place should have been - _"is copy initialisation and since C++17 ..."_] – Richard Critten Nov 28 '21 at 19:02
  • @RichardCritten Does copy initialization have a corresponding operator that can be overloaded/deleted just like the copy constructor does? In a larger example that I'm dealing with, I'd like to explicitly make private all ways of constructing the object since I want to enforce that an lvalue with the class type be never obtained outside the class definition. – Simeon Nov 29 '21 at 06:40
  • 1
    @Simeon Make the constructor(s) (default etc) private and use factory methods to create the object. Doing this would make `A a = A();` fail as `A()` would be a private constructor. – Richard Critten Nov 29 '21 at 09:45

0 Answers0