Solución para la deducción de argumentos de plantilla en el contexto no deducido
-
25-10-2019 - |
Pregunta
Considere el siguiente código:
#include <iostream>
template<class T>
struct outer {
struct inner {};
};
template<class T>
std::ostream& operator<<(std::ostream & stream,
typename outer<T>::inner const& value) {
std::cout << "An outer::inner!";
return stream;
}
int main() {
outer<float>::inner foo;
std::cout << foo << std::endl; // does not compile
}
Esto no se compila, porque typename outer<T>::inner
es un contexto no ocurrido (como se explica aquí), lo que significa que el compilador no puede deducir la plantilla-argumento (leer esta respuesta para el por qué). Como lo veo, tengo dos opciones para que funcione:
- Muevete
inner
fuera deouter
y conviértalo en una clase de clase. Prefiero este, porque el impacto en el código de uso es más pequeño. - Agrega un
to_string
-Método al interior.
¿Hay otras soluciones para esto (que no dan como resultado una sintaxis fea en el código de uso)?
Solución
Puede mover el operador al cuerpo de la clase interior y poner friend
antes de eso. Luego reemplace el tipo de parámetro por solo inner
.
Otra técnica es derivar interna de una base CRTP parametrizada por Inner. Luego haga que el parámetro escriba la clase CRTP y coloque la referencia del parámetro a la derivada inner
clase, el tipo de que se da el argumento de la plantilla que deduce.