c++ language-design template-specialization partial-specialization function-templates

c++ - ¿Por qué la plantilla de función no puede ser parcialmente especializada?



language-design template-specialization (4)

Bueno, realmente no puede realizar una especialización parcial de función / método, pero sí puede realizar una sobrecarga.

template <typename T, typename U> T fun(U pObj){...} // acts like partial specialization <T, int> AFAIK // (based on Modern C++ Design by Alexandrescu) template <typename T> T fun(int pObj){...}

Es el camino pero no sé si te satisface.

Sé que la especificación de lenguaje prohíbe la especialización parcial de la plantilla de función.

Me gustaría saber la razón por la que lo prohíbe? ¿No son útiles?

template<typename T, typename U> void f() {} //allowed! template<> void f<int, char>() {} //allowed! template<typename T> void f<char, T>() {} //not allowed! template<typename T> void f<T, int>() {} //not allowed!


Como puedes especializar parcialmente las clases, puedes usar un functor:

#include <iostream> template < typename dtype , int k > struct fun { int operator()() { return k ; } } ; template < typename dtype > struct fun < dtype , 0 > { int operator()() { return 42 ; } } ; int main ( int argc , char * argv[] ) { std::cout << fun<float,5>()() << std::endl ; std::cout << fun<float,0>()() << std::endl ; }


En general, no se recomienda especializar plantillas de funciones, debido a problemas con la sobrecarga. Aquí hay un buen artículo del C / C ++ Users Journal: http://www.gotw.ca/publications/mill17.htm

Y contiene una respuesta honesta a tu pregunta:

Por un lado, no puedes especializarlos parcialmente, prácticamente porque el lenguaje dice que no puedes.


AFAIK que ha cambiado en C ++ 0x.

Supongo que solo fue un descuido (considerando que siempre se puede obtener el efecto de especialización parcial con un código más detallado, al colocar la función como miembro static de una clase).

Puede buscar el DR (Informe de defectos) correspondiente, si lo hay.

EDITAR : revisando esto, encuentro que otros también han creído eso, pero nadie es capaz de encontrar tal apoyo en el borrador del estándar. Este subproceso SO parece indicar que C ++ 0x no admite la especialización parcial de las plantillas de función .

EDIT 2 : solo un ejemplo de lo que quise decir con "colocar la función como miembro static de una clase":

#include <iostream> using namespace std; // template<typename T, typename U> void f() {} //allowed! // template<> void f<int, char>() {} //allowed! // template<typename T> void f<char, T>() {} //not allowed! // template<typename T> void f<T, int>() {} //not allowed! void say( char const s[] ) { std::cout << s << std::endl; } namespace detail { template< class T, class U > struct F { static void impl() { say( "1. primary template" ); } }; template<> struct F<int, char> { static void impl() { say( "2. <int, char> explicit specialization" ); } }; template< class T > struct F< char, T > { static void impl() { say( "3. <char, T> partial specialization" ); } }; template< class T > struct F< T, int > { static void impl() { say( "4. <T, int> partial specialization" ); } }; } // namespace detail template< class T, class U > void f() { detail::F<T, U>::impl(); } int main() { f<char const*, double>(); // 1 f<int, char>(); // 2 f<char, double>(); // 3 f<double, int>(); // 4 }