Search code examples
c++constructorvariable-assignmentshared-ptr

Differences between assignment constructor and others in C++


Consider:

std::shared_ptr<Res> ptr=new Res();

The above statement doesn't work. The compiler complains there isn't any viable conversion....

While the below works

std::shared_ptr<Res> ptr{new Res()} ;

How is it possible?!

Actually, what are the main differences in the constructor{uniform, parentheses, assignments}?


Solution

  • The constructor of std::shared_ptr taking a raw pointer is marked as explicit; that's why = does not allow you to invoke this constructor.

    Using std::shared_ptr<Res> ptr{new Res()}; is syntax that allows you to call the an explicit constructor to initialize the variable.

    std::shared_ptr<Res> ptr=new Res();
    

    would invoke an implicit constructor taking a pointer to Res as single parameter, but not an explicit one.

    Here's a simplified example using a custom class with no assignment operators and just a single constructor:

    class Test
    {
    public:
        Test(int i) { }
    
        // mark all automatically generated constructors and assignment operators as deleted
        Test(Test&&) = delete;
        Test& operator=(Test&&) = delete;
    };
    
    int main()
    {
        Test t = 1;
    }
    

    Now change the constructor to

    explicit Test(int i) { }
    

    and the main function will no longer compile; the following alternatives would still be viable:

    Test t(1);
    Test t2{1};