2012-08-08 11 views
9

En el código C++ a continuación, foobar se define primero para un solo parámetro double, y nuevamente para un único parámetro del tipo Foo. Ambos están definidos dentro del espacio de nombres global.Acceso al espacio de nombres global C++ desde otro espacio de nombre

Dentro del espacio de nombres one, se define una sobrecarga adicional de foobar, con un solo parámetro del tipo Bar. A partir de esta versión de foobar, una llamada no calificada al foobar con un argumento double (42.0) fallará. Una llamada similar a foobar, esta vez calificada con el operador de resolución de ámbito (: :), también con un argumento double, tendrá éxito.

Por otro lado, una llamada no calificada a foobar, con un argumento de tipo Foo, se realiza correctamente. Una llamada a foobar con un argumento Foo, calificado por el operador de resolución del alcance, también tiene éxito.

¿Por qué los dos escenarios se comportan de manera diferente? Uso tanto gcc 4.7 como clang ++ 3.2.

struct Foo {}; 
struct Bar {}; 

double foobar(double x) { return x; } 
Foo foobar(Foo f) { return f; } 

namespace one { 

    Bar foobar(Bar b) { 
    //foobar(42.0); // error: can't convert to Bar 
    ::foobar(42.0); 

    Foo f; 
     foobar(f); // no problem 
    ::foobar(f); 
    return b; 
    } 
}; 

Respuesta

8

Argument dependent lookup.

En la llamada foobar(f) se considerarán las funciones del espacio de nombres de Foo.

No funciona para double porque ese tipo no está declarado en ningún espacio de nombres.

+0

Como una adición a la última oración: la búsqueda de nombre no calificada se detiene tan pronto como encuentra un * nombre * coincidente, primero teniendo en cuenta los ámbitos locales y solo si no encuentra ningún nombre buscará los ámbitos superior y global . – Xeo

+0

Gracias Bo. El enlace a ADL deja las cosas claras. – user2023370

+0

@Xeo: ¿Eso no implicaría que la llamada a 'foobar (f)' fallaría al encontrar 'foobar (Bar b)'? – user2023370

Cuestiones relacionadas