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
?
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:
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>;
};