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
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 ns2
donde 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.
Porque cuando estás dentro de un espacio de nombre (ns2) tiene prioridad sobre cualquier otro si los nombres no están calificados.
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()?
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>()); ???
}
};
muchas gracias por su solución práctica. – xmllmx
- 1. using namespace
- 2. VS2008 (+?) Error del compilador con funciones de plantilla y 'using namespace'
- 3. ¿Qué me exige declarar "using namespace std;"?
- 4. ¿`Using Namespace;` consume más memoria?
- 5. ¿Qué efecto tiene eliminar las instantáneas EC2?
- 6. ¿Por qué "usar lib" no tiene efecto de esta manera?
- 7. "using" namespace equivalent en el marcado ASP.NET
- 8. ¿Por qué el .htaccess no tiene ningún efecto?
- 9. Plantilla en C++, ¿por qué tiene que usar enum
- 10. "using namespace" para los comentarios de Doxygen
- 11. C# add using declaration for namespace para todas las clases
- 12. ¿Por qué el uso de boost :: tuple's .get no funciona en funciones de plantilla en gcc?
- 13. ¿Por qué la propiedad '#weight' a veces no tiene ningún efecto en los formularios de Drupal?
- 14. La etiqueta 'XXX' no existe en el espacio de nombres XML 'clr-namespace: YYY'
- 15. NSApplication endSheet: no tiene efecto
- 16. UpdatePanel.Visible = true no tiene efecto
- 17. El control 'xxx' no tiene ventana principal
- 18. ¿Puedo declarar "using namespace" dentro de una clase de C++?
- 19. ¿Por qué C# no tiene funciones anidadas léxicamente?
- 20. setImageBitmap no tiene efecto visible
- 21. ¿Por qué las conversiones de operador no requieren implícitamente funciones con plantilla? (C++)
- 22. PHP setlocale no tiene efecto
- 23. HttpURLConnection setConnectTimeout() no tiene efecto
- 24. ¿Qué efecto tiene HOLDLOCK en UPDLOCK?
- 25. ¿Por qué hay -moz-XXX y -webkit-XXX en el CSS3?
- 26. Configuración de cell.ReadOnly no tiene ningún efecto
- 27. La asignación a la variable no tiene ningún efecto?
- 28. namespace no encontrado!
- 29. ¿Por qué Java `BitSet` no tiene las funciones` shiftLeft` y `shiftRight`?
- 30. Argumentos de plantilla para las funciones de plantilla
muchas gracias. Tus respuestas son siempre rápidas y correctas. – xmllmx