2010-12-15 3 views
5
namespace ns1 
{ 
    template <class T> 
    void f(T) 
    { 
     cout << typeid(T).name() << endl; 
    } 
}; 

using namespace ns1; 

namespace ns2 
{ 
    void f(int) 
    { 
     cout << "int" << endl; 
    } 

    void test() 
    { 
     f(vector<int>()); // Error! 
     // Why not call ns1::f<vector<int>>(vector<int>()); ??? 
    } 
}; 

Respuesta

9

Esto no tiene nada que ver con las plantillas, pero sin la búsqueda de nombres.

Esto es lo que dice la norma de 3,4/1 (búsqueda de nombres):

búsqueda de nombre, la hallará una declaración inequívoca para el nombre (véase 10.2). La búsqueda de nombres puede asociar más de una declaración con un nombre si encuentra que el nombre es un nombre de función; se dice que las declaraciones forman un conjunto de funciones sobrecargadas (13.1). La resolución de sobrecarga (13.3) tiene lugar después de que la búsqueda de nombre se haya realizado correctamente. Las reglas de acceso (cláusula 11) son consideradas una sola búsqueda de nombre y la resolución de sobrecarga de función (si es aplicable ) han tenido éxito.

Y en 3.4.1 (búsqueda de nombre no calificado):

búsqueda de nombre termina tan pronto como la declaración se encuentra el nombre

En su caso, es f un nombre no calificado. Se busca en el alcance inmediato, y en el espacio de nombres ns2donde se encuentra una declaración. La búsqueda de nombre finaliza aquí, y la resolución de sobrecarga entra en juego: no hay sobrecarga en el conjunto de candidatos que coincida con el tipo de argumento std::vector<int>, por lo que el programa está mal formado.

+0

muchas gracias. Tus respuestas son siempre rápidas y correctas. – xmllmx

2

Porque cuando estás dentro de un espacio de nombre (ns2) tiene prioridad sobre cualquier otro si los nombres no están calificados.

2

ns2 tendrá prioridad ya que ese es el espacio de nombre en el que se encuentra actualmente. ¿Por qué debería el compilador pensar que realmente quiso decir ns1 :: f()?

1

Esto debería funcionar:

namespace ns1 
{ 
    template <class T> 
    void f(T) 
    { 
     cout << typeid(T).name() << endl; 
    } 
}; 



namespace ns2 
{ 
    using ns1::f; 
    void f(int) 
    { 
     cout << "int" << endl; 
    } 

    void test() 
    { 
     f(vector<int>()); // Error! 
     // Why not call ns1::f<vector<int>>(vector<int>()); ??? 
    } 
}; 
+0

muchas gracias por su solución práctica. – xmllmx

Cuestiones relacionadas