Escribí un pequeño contenedor de C++ alrededor de algunas partes de GSL y encontré el siguiente acertijo (para mí). El código (reducida a sus elementos esenciales) es como sigue:Llamada ambigua del constructor sobrecargado debido a la superclase (paso por valor)
#include <stdlib.h>
struct gsl_vector_view {};
class Vector : protected gsl_vector_view {
public:
Vector (const Vector& original);
Vector (const gsl_vector_view view);
};
class AutoVector : public Vector {
public:
explicit AutoVector (const size_t dims);
};
void useVector (const Vector b) {}
void test() {
const AutoVector ov(2);
useVector(ov);
}
no se compilará usando gcc 4.4.5 g ++ -c v.cpp pero dió
In function ‘void test()’:
19: error: call of overloaded ‘Vector(const AutoVector&)’ is ambiguous
7: note: candidates are: Vector::Vector(gsl_vector_view)
6: note: Vector::Vector(const Vector&)
19: error: initializing argument 1 of ‘void useVector(Vector)’
me sorprende que la protected clase base gsl_vector_view es tomada en consideración por la llamada de useVector (Vector). Hubiera pensado que useVector pertenece al "público general" en el lenguaje de "The C++ Programming Language", 3rd e., P. 405 y por lo tanto no tiene acceso a esa información protegida y, por lo tanto, no puede ser confundida por ella. Sé que puede deshacerse de la ambigüedad al declarar el constructor como
explicit Vector (const gsl_vector_view view);
Lo que yo no sabía (y, sinceramente, no entiendo tampoco), es que la ambigüedad de la llamada sobrecarga desaparece cuando declarar el constructor como
Vector (const gsl_vector_view& view);
es decir, pasar el argumento de referencia (que yo consideraría todos modos la forma correcta de hacer las cosas).
+1, No tiene nada que ver con la herencia 'protected'; así que reformatear la pregunta. – iammilind
por cierto. la ambigüedad desaparece cuando declaras useVector para tomar una referencia también – PlasmaHH