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