template friendship example and c++ templates c++11 friend

c++ - friendship - declarar la función de amigo de plantilla de la clase de plantilla



friendship and inheritance c++ (2)

Tengo una plantilla de clase Obj y una plantilla de función make_obj . Obj tiene un constructor único private definido, que toma una referencia a su tipo de plantilla para vincularse.

template <typename T> class Obj { private: T& t; Obj(T& t) : t{t} { } }; template <typename T> Obj<T> make_obj(T& t) { return {t}; }

Lo que quiero es declarar la función make_obj un friend para que pueda crear Obj ''s, pero nadie más puede hacerlo (excepto a través de la copia ctor).

He intentado varias declaraciones de amigos incluyendo

friend Obj make_obj(T&);

y

template <typename T1, typename T2> friend Obj<T1> make_obj(T2&);

Este último es un intento poco deseable de hacer todas las make_obj de plantilla de make_obj amigos de la clase Obj . Sin embargo, en ambos casos me sale el mismo error:

error: calling a private constructor of class ''Obj<char const[6]>'' return {t}; ^ note: in instantiation of function template specialization ''make_obj<const char *>'' requested here auto s = make_obj("hello"); ^

tratando de hacer make_obj("hello"); para fines de ejemplo.

¿Cómo puedo permitir que solo make_obj acceda al contructor de valor de Obj ?


Con la sintaxis de tipo de retorno automático, solo necesita reenviar declarar la función y todo funciona. Aquí hay un ejemplo

template <typename T> auto make_obj(T t); template <typename T> class Obj { private: T & t; Obj (T & t) : t(t) { } Obj() = delete; friend auto make_obj<T>(T t); }; template <typename T> auto make_obj(T t) { return Obj<T>{t}; } int main() { make_obj(1); return 0; }

https://ideone.com/3k86gx


Necesitas unas pocas declaraciones hacia adelante:

template <typename T> class Obj; template <typename T> Obj<T> make_obj(T t); template <typename T> class Obj { private: T & t; Obj (T & t) : t(t) { } Obj() = delete; friend Obj make_obj<T>(T t); }; template <typename T> Obj<T> make_obj(T t) { return Obj<T>(t); }

ejemplo vivo

Y BTW: No creo que realmente quieras T & t; para la variable miembro de su clase. Probablemente T t; Es una mejor opción;)