Skip to main content
formatting, make sure <Args> isn't treated as invalid HTML
Source Link
user743382
user743382

Looking at the requirements for std::make_shared in 20.7.2.2.6 shared_ptr creation [util.smartptr.shared.create], paragraph 1:

Requires:Requires: The expression ::new (pv) T(std::forward(args)...)::new (pv) T(std::forward<Args>(args)...), where pvpv has type void*void* and points to storage suitable to hold an object of type TT, shall be well formed. AA shall be an allocator (17.6.3.5). The copy constructor and destructor of AA shall not throw exceptions.

Since the requirement is unconditionally specified in terms of that expression and things like scope aren't taken into account, I think tricks like friendship are right out.

A simple solution is to derive from A. This needn't require making A an interface or even a polymorphic type.

// interface in header std::shared_ptr<A> make_a(); // implementation in source namespace { struct concrete_A: public A {}; } // namespace std::shared_ptr<A> make_a() { return std::make_shared<concrete_A>(); } 

Looking at the requirements for std::make_shared in 20.7.2.2.6 shared_ptr creation [util.smartptr.shared.create], paragraph 1:

Requires: The expression ::new (pv) T(std::forward(args)...), where pv has type void* and points to storage suitable to hold an object of type T, shall be well formed. A shall be an allocator (17.6.3.5). The copy constructor and destructor of A shall not throw exceptions.

Since the requirement is unconditionally specified in terms of that expression and things like scope aren't taken into account, I think tricks like friendship are right out.

A simple solution is to derive from A. This needn't require making A an interface or even a polymorphic type.

// interface in header std::shared_ptr<A> make_a(); // implementation in source namespace { struct concrete_A: public A {}; } // namespace std::shared_ptr<A> make_a() { return std::make_shared<concrete_A>(); } 

Looking at the requirements for std::make_shared in 20.7.2.2.6 shared_ptr creation [util.smartptr.shared.create], paragraph 1:

Requires: The expression ::new (pv) T(std::forward<Args>(args)...), where pv has type void* and points to storage suitable to hold an object of type T, shall be well formed. A shall be an allocator (17.6.3.5). The copy constructor and destructor of A shall not throw exceptions.

Since the requirement is unconditionally specified in terms of that expression and things like scope aren't taken into account, I think tricks like friendship are right out.

A simple solution is to derive from A. This needn't require making A an interface or even a polymorphic type.

// interface in header std::shared_ptr<A> make_a(); // implementation in source namespace { struct concrete_A: public A {}; } // namespace std::shared_ptr<A> make_a() { return std::make_shared<concrete_A>(); } 
Source Link
Luc Danton
  • 35.6k
  • 8
  • 73
  • 117

Looking at the requirements for std::make_shared in 20.7.2.2.6 shared_ptr creation [util.smartptr.shared.create], paragraph 1:

Requires: The expression ::new (pv) T(std::forward(args)...), where pv has type void* and points to storage suitable to hold an object of type T, shall be well formed. A shall be an allocator (17.6.3.5). The copy constructor and destructor of A shall not throw exceptions.

Since the requirement is unconditionally specified in terms of that expression and things like scope aren't taken into account, I think tricks like friendship are right out.

A simple solution is to derive from A. This needn't require making A an interface or even a polymorphic type.

// interface in header std::shared_ptr<A> make_a(); // implementation in source namespace { struct concrete_A: public A {}; } // namespace std::shared_ptr<A> make_a() { return std::make_shared<concrete_A>(); }