#include #include class C { protected: struct Protected { private: Protected() {}; public: static Protected make() { return { }; } }; int m_x; private: struct Private { private: Private() {}; public: static Private make() { return { }; } }; int m_y; public: /* private constructor: */ C(Private, int x, int y) : m_x(x), m_y(y) { } /* protected constructor: */ C(Protected, int x) : C(Private::make(), x, 2*x) { } void leak_private_type(Private) { } static std::unique_ptr Create(int x) { return std::unique_ptr(new C(Private::make(), x, 2*x)); } }; class D : public C { private: struct Private { }; public: D(Private&, int x) : C(Protected::make(), x) { } static std::shared_ptr Create(int x) { Private p; return std::make_shared(p, 4*x); } }; class A { struct this_is_private { }; public: explicit A(const this_is_private &, int) {} static ::std::shared_ptr create(int x) { return ::std::make_shared(this_is_private{}, x); } protected: A(const A &) = delete; const A &operator =(const A &) = delete; }; ::std::shared_ptr foo(int x) { return A::create(x); } /* usage: decltype(return_args(&Class::memberfunction)) */ template std::tuple return_args(Result (Base::*func)(Args...)); /* usage: decltype(result_of(&Class::memberfunction)) */ template Result result_of(Result (Base::*func)(Args...)); /* usage: decay_tuple_element<0, decltype(return_args(&Class::memberfunction))> */ template using decay_tuple_element = typename std::decay::type>::type; struct _is_static_castable_impl { template(std::declval<_From>()))> static std::true_type __test(int); template static std::false_type __test(...); }; template struct is_static_castable : public _is_static_castable_impl { typedef decltype(__test<_From, _To>(0)) type; }; template using is_static_castable_t = typename is_static_castable<_From, _To>::type; int main() { auto c = C::Create(0); auto d = D::Create(0); typedef decay_tuple_element<0, decltype(return_args(&C::leak_private_type))> Private; Private::make(); auto a1 = foo(0); auto a2 = std::shared_ptr(new A({}, 0)); // C c1({}, 0, 0); }