Suponiendo que tenía dos clases, la primera para escribir tipos primitivos (bool
, int
, float
, etc.) y la segunda que se extiende el primero en escribir también los tipos complejos:¿Por qué C++ prefiere este método de plantilla a una sobrecarga de método?
struct Writer {
virtual void Write(int value) = 0;
};
struct ComplexWriter : public Writer {
template <typename TValue> void Write(const TValue &value) {
boost::any any(value);
Write(any);
}
//virtual void Write(int value) = 0; // see question below
virtual void Write(const boost::any &any) = 0;
};
La idea es que si alguien llama al myWriter.Write(someIntValue);
, la sobrecarga int recibirá prioridad sobre el método de plantilla.
En cambio, mi compilador (Visual C++ 11.0 RC) siempre elige el método de la plantilla. El siguiente fragmento de código, por ejemplo, se imprimirá Wrote any
a la consola:
struct ComplexWriterImpl : public ComplexWriter {
virtual void Write(int value) { std::cout << "Wrote an int"; }
virtual void Write(const boost::any &any) { std::cout << "Wrote any"; }
};
void TestWriter(ComplexWriter &writer) {
int x = 0;
writer.Write(x);
}
int main() {
ComplexWriterImpl writer;
TestWriter(writer);
}
El comportamiento cambia repentinamente cuando declaro el método Write(int)
en la clase ComplexWriter
también (véase la línea comentada en el primer fragmento). A continuación, imprime Wrote an int
en la consola.
¿Es así como se debe comportar mi compilador? ¿El estándar C++ dice explícitamente que solo las sobrecargas definidas en la misma clase (y no una clase base) se priorizarán sobre un método con plantilla?
No veo donde se sobrecarga un método de toma de int con una plantilla de. Tienes dos clases no relacionadas, 'Writer' con un método que toma' int' y 'ComplexWriter' con un método de plantilla (y un método que toma' boost :: any const & '). En su código de prueba utiliza 'ComplexWriter', así que por supuesto llamará a un miembro de' ComplexWriter'. Si realmente esperaba que llamara a un miembro de la clase "Escritor" sin relación alguna, ¿podría explicar por qué (y cómo) debería hacerlo? – celtschk
Menciona que 'ComplexWriter' extiende' Writer', pero en el código que enumeró no hereda de 'Writer'. ¿Es esta la configuración correcta? – Attila
Gracias por señalar eso. Sí, se suponía que ComplexWriter derivaba de Writer. Actualicé la pregunta en consecuencia. El resultado sigue siendo el mismo (aunque, por supuesto, se olvidó de especificar que la clase base se conecta al núcleo de mi pregunta. Outch). – Cygon