Home > Software engineering >  Does make_shared ignore explicit specifier?
Does make_shared ignore explicit specifier?

Time:10-21

Consider the following example:

#include <iostream>
#include <memory>

struct A
{
    explicit A(int x) 
    { 
        std::cout << x << std::endl;
    }
};

void Foo(A ) {}

std::shared_ptr<A> Foo2(int x)
{
    // why does this work?
    return std::make_shared<A>(x);
}

int main()
{
    A a(0);
    Foo(a);
    // Foo(1); does not compile
    Foo2(2);
}

I have a class A with an explicit marked constructor so that it doesn't convert from int to the class A implicitly. But in a call to std::make_shared I can call and create this class by only passing an int. Why is that possible and is there something wrong in the way how I do it?

CodePudding user response:

This is expected behavior, because std::make_shared performs direct-intialization, which considers explicit constructors too.

The object is constructed as if by the expression ::new (pv) T(std::forward<Args>(args)...)

Direct-initialization is more permissive than copy-initialization: copy-initialization only considers non-explicit constructors and non-explicit user-defined conversion functions, while direct-initialization considers all constructors and all user-defined conversion functions.

Foo(1); doesn't work because the parameter gets copy-initialized, which won't consider explicit constructors.

  • Related