Why can't make_shared construct this object?
//auto foo = std::shared_ptr<Foo>(new Foo(i)); "works"
Here you access Foo
's constructor from inside Foo
and then pass this pointer to std::shared_ptr
, which is fine.
auto foo = std::make_shared<Foo>(i);
Here std::make_shared
tries to access Foo
's constructor which is protected
and thus not allowed.
@SombreroChicken provided a good answer why this is the case. I want to provide a possible solution
#include <iostream>
#include <memory>
class Foo {
private:
struct Token{};
public:
std::shared_ptr<Foo> getFoo(int i) {
auto foo = std::make_shared<Foo>(i, Token{});
//auto foo = std::shared_ptr<Foo>(new Foo(i)); "works"
return foo;
}
Foo(int i, Token) : Foo(i) {}
protected:
Foo(int i) {std::cout << "foo" << std::endl; }
};
int main(int argc, const char * argv[]) {
}
it works by making a public constructor that requires something only Foo can make, so anyone who received the 'token' can call the constructor
NOTE: passing such tag parameters may be better done as the first parameter, because
to be consistent with standard library
certain compilers (notably msvc) have special handling of it that improves compile times