Sé que la especificación del 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!
template<typename T, typename U> void f(T t, U u) {}
tambiéntemplate<> void f(int t, char u) {}
está permitido.Respuestas:
AFAIK que ha cambiado en C ++ 0x.Supongo que fue solo un descuido (considerando que siempre se puede obtener el efecto de especialización parcial con un código más detallado, colocando la función como
static
miembro 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 puede encontrar tal apoyo en el borrador del estándar. Este hilo SO parece indicar que la especialización parcial de las plantillas de funciones no es compatible con C ++ 0x .
EDICIÓN 2 : solo un ejemplo de lo que quise decir con "colocar la función como
static
miembro 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 }
fuente
Bueno, realmente no puede hacer una especialización parcial de funciones / métodos, sin embargo, puede hacer 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.
fuente
En general, no se recomienda especializar las plantillas de funciones en absoluto, debido a problemas de 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 su pregunta:
fuente
Dado que puede especializar clases parcialmente, puede 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 ; }
fuente
()()
sintaxis fea .