Pregunta

Recientemente me llamó la atención ese miembro funciona completamente sombra funciones gratuitas con el mismo nombre cuando están dentro de la clase.Y con completamente quiero decir que todas las funciones gratuitas con el mismo nombre no se consideran en absoluto para la resolución de sobrecarga.Puedo entender por qué se hace con algo como esto:

void f();

struct S
{
    void f();

    void g()
    {
        f(); // calls S::f instead of ::f
    }
};

donde las funciones tienen firmas idénticas, es natural ya que el alcance de las variables funciona de la misma manera.Pero, ¿por qué prohibir llamadas inequívocas donde la función gratuita tiene una firma diferente como esta?

void f();

struct S
{
    void f(int x);

    void g()
    {
        f(); // fails to compile attempting to call S::f, which has wrong signature
    }
};

No estoy preguntando cómo llamar a un sombreado función gratuita desde dentro de la clase.Lo que quiero saber es el fundamento de este diseño.

¿Fue útil?

Solución

Para la búsqueda de nombres no calificados, solo se considera un ámbito a la vez y, si la búsqueda en ese ámbito no arroja ningún resultado, se busca en el siguiente ámbito superior.En tu caso, sólo SSe busca el alcance.

Pero, ¿por qué prohibir llamadas inequívocas donde la función gratuita tiene una firma diferente como esta?

El problema es ese búsqueda de nombre no se preocupa más que del nombre, del identificador.Es completamente ajeno al hecho de que desea llamar a una función, solo ve un identificador.La misma búsqueda de nombre ocurre si solo usas auto x = f;, y si lo piensas de esa manera, hay muy buenas razones por las que solo deseas un alcance de búsqueda muy limitado.Cualquier otra cosa simplemente sorprendería al usuario.

Otros consejos

Hay una regla especial, muy sorprendente, (pero no se aplica a su ejemplo) que indica que una vez que se encuentra el nombre del miembro de la clase , no se buscan los ámbitos de espacio de nombres:

#include <string>

struct C {
    std::string s;

    explicit C (std::string);

    void swap (C& rhs) {
        swap (s, rhs.s); // error: swap is C::swap
    }   
};

void swap (C& lhs, C& rhs) {
    swap (lhs.s, rhs.s); // std::swap(string,string)
}

imo, esto es la locura.

Pero, ¿por qué prohibir las llamadas inequívocas donde la función libre tiene una firma diferente como esta:

La búsqueda de nombres ocurre antes de sobrecargar la resolución:

  • Si la búsqueda es ambigua, la resolución de sobrecarga no se realiza.
  • Si no se encuentra ninguna función viable por la búsqueda, no se prueba ninguna otra ronda de búsqueda.

Las reglas son suficientemente complejas sin "feedback" entre la sobrecarga y la búsqueda de nombres.Sugeriría la simplificación (como eliminar la regla del nombre del alcance del espacio de nombres Hides, y la eliminación de la búsqueda de nombre ambiguo) en lugar de complejar.

No puedo proporcionar una respuesta autorizada (tal vez algunos recuerden una cotización de Design and Evolution of C++ o en realidad haya estado en el comité en ese momento), pero mi primera suposición sería fallar exactamente en los casos que muestren.Es fácil olvidar cuántas cosas están en alcance en un momento determinado.Además, la resolución de sobrecarga puede ser bastante compleja y puede haber argumentos y conversión por defecto.Así que preferiría tener el alcance más limitado en ese caso para estar siempre seguro de lo que se llama exactamente.

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