I am writing a class ptr_scope_manager to manage the creation and destruction of pointers in a given scope. I have studied the answers from this question:
Private constructor inhibits use of emplace[_back]() to avoid a move
And it appears that if I want to manage the creation of an object whose class has a private constructor, my internal std::vector can use push_back but not emplace_back to construct the object. This is because emplace_back uses an internal class to construct the object. That means friending the ptr_scope_manager is not sufficient to allow it to create objects with private constructors.
So what I have done is make two create methods, one for objects with public constructors and one for objects with private constructors that have friended the ptr_scope_manager.
template<typename Type> class ptr_scope_manager { private: std::vector<Type> ptrs; public: template<typename... Args> Type* create_private(Args... args) { ptrs.push_back(Type(args...)); return &ptrs.back(); } template<typename... Args> Type* create_public(Args... args) { ptrs.emplace_back(args...); return &ptrs.back(); } }; class public_ctor { int i; public: public_ctor(int i): i(i) {} // public }; class private_ctor { friend class ptr_scope_manager<private_ctor>; int i; private: private_ctor(int i): i(i) {} // private }; int main() { ptr_scope_manager<public_ctor> public_manager; ptr_scope_manager<private_ctor> private_manager; public_manager.create_public(3); public_manager.create_private(3); // private_manager.create_public(3); // compile error private_manager.create_private(3); } My question is this:
Is there any way I can use SFINAE (or otherwise?) to automatically select between create_public() and create_private() based on whether or not the template Type parameter has a public or private constructor? Perhaps utilizing std::is_constructible?
It would be nice to have only one create() method that auto-selects the more efficient create_public() method where possible and falling back on the slightly less efficient create_private when necessary.
std::is_constructibleandstd::enable_ifyou should be able to select which method to use.