stillanoob
stillanoob

Reputation: 1379

Unusual behavior of copy ctor

#include<iostream>
#include<string>

using namespace std;

class B;

class A {
    public:
        A(const A&) {   //copy ctor
            cout << "Copy ctor A\n";
        }
        A() {}  //default ctor
        A(const B&) {   //lets call this conversion ctor
            cout << "B to A conversion ctor\n";
        }
};

class B {
    public:

};

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

The above code prints B to A conversion ctor. But as per what I have discovered after looking around for a while, it should print

B to A conversion ctor
Copy ctor A

As first a temporary object of type A is created by conversion ctor and then that object is copied into a wherein copy ctor gets called. Also, when copy ctor is made private, statement A a = b; generates this error:

‘A::A(const A&)’ is private

which is obvious as to copy the temporary object into a copy ctor must be visible. So my question is why copy ctor is not being eventually called as evident from the output(please correct if am leading wrong somewhere here) even though it is required to be accessible?

Upvotes: 0

Views: 75

Answers (2)

songyuanyao
songyuanyao

Reputation: 172934

why copy ctor is not being eventually called as evident from the output

According to the standard, an implementation is allowed to omit the copy/move construction in certain criteria. In this case, a temporary A(constructed from b, and will be copied to a) 's construction is omitted.

$12.8/31 Copying and moving class objects [class.copy]

When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the constructor selected for the copy/move operation and/or the destructor for the object have side effects.

And

(31.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 type (ignoring cv-qualification), the copy/move operation can be omitted by constructing the temporary object directly into the target of the omitted copy/move

Upvotes: 0

TartanLlama
TartanLlama

Reputation: 65620

A a = b;

This form is called copy-initialization. The applicable rule states that in this case a temporary A object will be constructed from the B instance and that temporary will then be used to direct-initialize a.

However, the compiler is allowed to elide the copy as it is not necessary. Even though the elision is allowed, the class still needs to be copyable for the form to be valid.

You can see the result without elision by passing -fno-elide-constructors to GCC or Clang.

Upvotes: 2

Related Questions