Why is a public copy constructor required even if it is not invoked?

c++, constructor, oop

Solution

Here are the relevant bits of the C++ standard that are involved:

[dcl.init]/16, bullet 6, sub-bullet 1: If the initialization is direct-initialization, or if it is copy-initialization where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination, constructors are considered.... If no constructor applies, or the overload resolution is ambiguous, the initialization is ill-formed. [emphasis added]

In other words, it doesn't matter if a compiler optimization could elide the copy, the initialization is ill-formed because there are no applicable constructors. Of course, once you make the copy constuctor public, the following section applies:

[class.copy]/31: When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the copy/move constructor and/or destructor for the object have side effects.... This elision of copy/move operations, called copy elision, is permitted in the following circumstances (which may be combined to eliminate multiple copies):

bullet 3: when a temporary class object that has not been bound to a reference (12.2) would be copied/moved to a class object with the same cv-unqualified type, the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move

Problem

Having a public copy constructor will make the little program compile, but not showing the side effect "Copy". ``` #include <iostream> class X { public: X(int) { std::cout << "Construct" << std::endl; } // Having a public copy constructor will make the little program // compile, but not showing the side effect "Copy". private: X(const X&) { std::cout << "Copy" << std::endl; } private: X& operator = (const X&); }; int main() { X x = 1; return 0; } ```

Original source