tipos template sirven que programacion plantillas para los funciones ats c++ syntax argument-dependent-lookup

sirven - template en c++ pdf



¿Por qué ADL no encuentra plantillas de funciones? (3)

¿Qué parte de la especificación de C ++ restringe la búsqueda dependiente de los argumentos para que no encuentre plantillas de funciones en el conjunto de espacios de nombres asociados? En otras palabras, ¿por qué no se compila la última llamada en main ?

namespace ns { struct foo {}; template<int i> void frob(foo const&) {} void non_template(foo const&) {} } int main() { ns::foo f; non_template(f); // This is fine. frob<0>(f); // This is not. }


Editar: No, esto no es correcto. Ver la respuesta de @ Kornel .

No estoy del todo seguro, pero habiendo consultado el "Lenguaje de programación C ++" de Stroustrup, creo que la sección 13.8.4 del Apéndice C podría ser la causa.

Como frob es una plantilla, es posible que se lo especialice para i=0 en un punto después de llamarlo. Esto significa que la implementación se quedaría con dos formas posibles de elegir qué frob llamar, ya que parece que puede elegirla en el momento de la instanciación o al final del procesamiento de la unidad de traducción.

Entonces, creo que el problema es que podrías hacer

namespace ns { struct foo {}; template<int i> void frob(foo const&) {} } int main() { ns::foo f; frob<0>(f); return 0; } namespace ns { template<> void frob< 0 >(foo const&) { /* Do something different*/ } }


Esta parte lo explica:

Norma C ++ 03 14.8.1.6 :

[Nota: Para los nombres de funciones simples, la búsqueda dependiente del argumento (3.4.2) se aplica incluso cuando el nombre de la función no es visible dentro del alcance de la llamada. Esto se debe a que la llamada todavía tiene la forma sintáctica de una llamada de función (3.4.1). Pero cuando se utiliza una plantilla de función con argumentos de plantilla explícitos, la llamada no tiene la forma sintáctica correcta a menos que haya una plantilla de función con ese nombre visible en el punto de la llamada. Si no se muestra dicho nombre, la llamada no está sintácticamente bien formada y no se aplica la búsqueda dependiente de los argumentos. Si algún nombre es visible, se aplica la búsqueda dependiente del argumento y se pueden encontrar plantillas de funciones adicionales en otros espacios de nombres.

namespace A { struct B { }; template<int X> void f(B); } namespace C { template<class T> void f(T t); } void g(A::B b) { f<3>(b); //ill-formed: not a function call A::f<3>(b); //well-formed C::f<3>(b); //ill-formed; argument dependent lookup // applies only to unqualified names using C::f; f<3>(b); //well-formed because C::f is visible; then // A::f is found by argument dependent lookup }


Me gustaría refinar la respuesta ligeramente aceptada. No está claro en la pregunta de OP, pero la parte importante del estándar (citado por Kornel) es esta (énfasis mío):

Pero cuando se utiliza una plantilla de función con argumentos de plantilla explícitos , la llamada no tiene la forma sintáctica correcta

entonces lo que está prohibido es confiar en ADL y usar argumentos de plantilla explícitos. Desafortunadamente, el uso de argumentos de plantilla sin tipo requiere el uso de argumentos explícitos (a menos que tengan valores predeterminados).

A continuación se muestra el código de muestra que muestra esto .:

[live]

#include <string> #include <utility> namespace C { struct B { }; template<class T> void f(T t){} } void g(C::B b) { f(b); // OK //f<C::B>(b); // ill-formed: not a function call, but only // because explicit template argument were used std::string s; move(s); // OK //move<std::string&>(s); // Error, again because // explicit template argument were used std::move<std::string&>(s); // Ok } int main() { C::B b; g(b); }