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:

  1. Muevete inner fuera de outer y conviértalo en una clase de clase. Prefiero este, porque el impacto en el código de uso es más pequeño.
  2. 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)?

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top