c++ templates friend template-templates

c++ - Hacer amistad con un parámetro de plantilla de plantilla



templates friend (2)

Tengo una plantilla de clase con un parámetro de plantilla de plantilla, y quiero declarar este parámetro (es decir, todas sus especializaciones) como friend . Pero no puedo encontrar la sintaxis correcta.

template <template <class> class T> struct Foo { template <class U> friend T; // "C++ requires a type specifier for all declarations" template <class U> friend struct T; // "declaration of ''T'' shadows template parameter" template <class U> friend struct T<U>; // "cannot specialize a template template parameter" pretty<please> lets(be) friends T; // Compiler shook its standard output in pity };

¿Cómo puedo declarar un parámetro de plantilla de plantilla como friend ?

Fragmento de Coliru


He encontrado que este problema es muy interesante para la investigación. De acuerdo con el estándar (C ++ 11 y superior), esto debería funcionar bien, supongo:

template <template <class> class U> struct identity { template <typename T> using type = U<T>; }; template <template <class> class U> struct Foo { template <typename> friend class identity<U>::type; };

Debido a un nivel de direccionamiento indirecto, no hay ningún sombreado y reutilización de nombre aquí, y esta situación se describe como la siguiente:

cppreference :

Tanto la plantilla de función como las declaraciones de plantilla de clase pueden aparecer con el especificador de amigo en cualquier plantilla de clase o clase no local (...). En este caso, cada especialización de la plantilla se convierte en un amigo, ya sea implícitamente instanciado, parcialmente especializado o explícitamente especializado. Ejemplo: class A { template<typename> friend class B; } class A { template<typename> friend class B; }

Sin embargo, parece que clang y MSVC piensan lo contrario: ver coliru o godbolt . Además, sus mensajes de error no parecen tener sentido, por lo que parece un error del compilador (o simplemente un error de sintaxis detectado incorrectamente). GCC compila y ejecuta los fragmentos mencionados a la perfección, pero todavía no estoy seguro de que sea una solución correcta.


Las plantillas tienden a hacer que los programadores compliquen las cosas. No estoy exactamente seguro de lo que estás tratando de hacer, y sospecho que probablemente haya una mejor manera de hacerlo, pero esto debería funcionar.

template <template <class> class T, class U> class Foo { friend class T<U>; };