En este ejemplo, las clases Fooy Barse proporcionan desde una biblioteca. Mi clase Bazhereda de ambos.
struct Foo
{
void do_stuff (int, int);
};
struct Bar
{
virtual void do_stuff (float) = 0;
};
struct Baz : public Foo, public Bar
{
void func ()
{
do_stuff (1.1f); // ERROR HERE
}
};
struct BazImpl : public Baz
{
void do_stuff (float) override {};
};
int main ()
{
BazImpl () .func ();
}
Me sale el error de compilación reference to ‘do_stuff’ is ambiguousque me parece falso porque las dos firmas de funciones son completamente diferentes. Si do_stuffno fuera virtual, podría llamar Bar::do_stuffpara desambiguarlo, pero al hacerlo se rompe el polimorfismo y se produce un error de enlace.
¿Puedo hacer una funcllamada virtual do_stuffsin renombrar cosas?

Respuestas:
Puedes hacerlo:
Probado con wandbox gcc más reciente y se compila bien. Creo que es el mismo caso con sobrecargas de funciones, una vez que sobrecargas una no puedes usar implementaciones de clase base sin ellas
using.De hecho, esto no tiene nada que ver con las funciones virtuales. El siguiente ejemplo tiene el mismo error
GCC 9.2.0 error: reference to 'do_stuff' is ambiguous:Posible pregunta relacionada
fuente
La búsqueda de nombres y la resolución de sobrecarga son diferentes. El nombre debe encontrarse primero en un ámbito, es decir, debemos encontrar uno
Xpara quedo_stuffse resuelva el nombreX::do_stuff, independientemente del uso del nombre, y luego seleccione la resolución de sobrecarga entre las diferentes declaraciones deX::do_stuff.El proceso NO es identificar todos esos casos
A::do_stuff,B::do_stuffetc. que son visibles, y luego realizar una resolución de sobrecarga entre la unión de eso. En cambio, se debe identificar un solo alcance para el nombre.En este código:
Bazno contiene el nombredo_stuff, por lo que se pueden buscar las clases base. Pero el nombre aparece en dos bases diferentes, por lo que la búsqueda de nombres no puede identificar un alcance. Nunca llegamos tan lejos como la resolución de sobrecarga.La solución sugerida en la otra respuesta funciona porque introduce el nombre
do_stuffal alcance deBaz, y también introduce 2 sobrecargas para el nombre. Por lo tanto, la búsqueda de nombres determina esedo_stuffmedioBaz::do_stuffy luego selecciona la resolución de sobrecarga de las dos funciones que se conocen comoBaz::do_stuff.Por otro lado, el sombreado es otra consecuencia de la búsqueda de nombres (no es una regla en sí misma). La búsqueda de nombre selecciona el alcance interno, por lo que cualquier cosa en el alcance externo no coincide.
Otro factor de complicación ocurre cuando la búsqueda dependiente de argumentos está en juego. Para resumir muy brevemente, la búsqueda de nombres se realiza varias veces para una llamada de función con argumentos de tipo de clase: la versión básica como se describe en mi respuesta, y luego nuevamente para cada tipo de argumento. Luego, la unión de los ámbitos encontrados entra en el conjunto de sobrecarga. Pero eso no se aplica a su ejemplo ya que su función solo tiene parámetros de tipo incorporado.
fuente