Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why converting constructor needs copy constructor to be declared when explicit cast performed?

From what I learned, I thought Foo a = 1 is equivalent to Foo a = (Foo)1.

With copy constructor declared, yes, they both result in calling Converting constructor.

class Foo
{
public:
    // Converting constructor
    Foo(int n) : value_(n) { std::cout << "Converting constructor." << std::endl; }

    // Copy constructor
    Foo(const Foo&) { std::couut << "Copy constructor." << std::endl; }

private:
    int value_;
};

int main()
{
    Foo a = 1;         // OK - prints only "Converting constructor."
    Foo b = (Foo)1;    // OK - prints only "Converting constructor."
}

In contrast, without copy constructor, it doesn't compile even though it doesn't ever call copy constructor.

class Foo
{
public:
    // Converting constructor
    Foo(int n) : value_(n) { std::cout << "Converting constructor." << std::endl; }
    
    // Copy constructor deleted
    Foo(const Foo&) = delete;

private:
    int value_;
};

int main()
{
    Foo a = 1;         // OK - prints only "Converting constructor."
    Foo b = (Foo)1;    // Error C2280: 'Foo::Foo(const Foo &)': attempting to reference a deleted function
}

What makes difference? Thank you.

like image 823
Jeongmin Heo Avatar asked Dec 30 '25 08:12

Jeongmin Heo


1 Answers

Foo a = 1; calls Foo(int n). (Foo)1 also calls Foo(int n). Foo b = (Foo)1; calls copy constructor Foo(const Foo&). Until C++17 the last call can be elided but the copy constructor must be available. Since C++17 copy elision is mandatory and the copy constructor isn't necessary: https://en.cppreference.com/w/cpp/language/copy_elision

Probably you're using a C++ standard before C++17 and the copy constructor is required but not called.

"From what I learned, I thought Foo a = 1 is equivalent to Foo a = (Foo)1." That's not equivalent. The first is one constructor call and the second is two constructor calls but one call can/must be elided.

like image 73
Thomas Sablik Avatar answered Dec 31 '25 23:12

Thomas Sablik