c++ templates c++14 unique-ptr friend-function

c++ - Cómo hacer std:: make_unique un amigo de mi clase



templates c++14 (1)

Quiero declarar que std::make_unique funciona como un amigo de mi clase. La razón es que quiero declarar que mi constructor está protected y proporcionar un método alternativo para crear el objeto utilizando unique_ptr . Aquí hay un código de ejemplo:

#include <memory> template <typename T> class A { public: // Somehow I want to declare make_unique as a friend friend std::unique_ptr<A<T>> std::make_unique<A<T>>(); static std::unique_ptr<A> CreateA(T x) { //return std::unique_ptr<A>(new A(x)); // works return std::make_unique<A>(x); // doesn''t work } protected: A(T x) { (void)x; } }; int main() { std::unique_ptr<A<int>> a = A<int>::CreateA(5); (void)a; return 0; }

Ahora mismo me sale este error:

Start In file included from prog.cc:1: /usr/local/libcxx-head/include/c++/v1/memory:3152:32: error: calling a protected constructor of class ''A<int>'' return unique_ptr<_Tp>(new _Tp(_VSTD::forward<_Args>(__args)...)); ^ prog.cc:13:21: note: in instantiation of function template specialization ''std::__1::make_unique<A<int>, int &>'' requested here return std::make_unique<A>(x); // doesn''t work ^ prog.cc:22:41: note: in instantiation of member function ''A<int>::CreateA'' requested here std::unique_ptr<A<int>> a = A<int>::CreateA(5); ^ prog.cc:17:5: note: declared protected here A(T x) { (void)x; } ^ 1 error generated. 1 Finish

¿Cuál es la forma correcta de declarar std::make_unique como amigo de mi clase?


make_unique perfect reenvía los argumentos que le pasas; en su ejemplo, está pasando un lvalue ( x ) a la función, por lo que deducirá el tipo de argumento como int& . La declaración de la función de tu friend debe ser

friend std::unique_ptr<A> std::make_unique<A>(T&);

Del mismo modo, si tuviera que move(x) dentro de CreateA , la declaración de friend debería ser

friend std::unique_ptr<A> std::make_unique<A>(T&&);

Esto hará que el código se compile , pero de ninguna manera es una garantía de que se compilará en otra implementación porque, por lo que sabe, make_unique reenvía sus argumentos a otra función auxiliar interna que realmente crea una instancia de su clase, en cuyo caso el ayudante lo haría. necesito ser un friend