Je sais que la spécification du langage interdit la spécialisation partielle du modèle de fonction.
J'aimerais savoir pourquoi il l'interdit? Ne sont-ils pas utiles?
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!
c++
language-design
template-specialization
partial-specialization
function-templates
Nawaz
la source
la source
template<typename T, typename U> void f(T t, U u) {}
aussitemplate<> void f(int t, char u) {}
est autorisé.Réponses:
AFAIK qui a changé dans C ++ 0x.Je suppose que c'était juste un oubli (étant donné que vous pouvez toujours obtenir l'effet de spécialisation partielle avec un code plus détaillé, en plaçant la fonction en tant que
static
membre d'une classe).Vous pouvez rechercher le DR (rapport d'anomalie) pertinent, s'il y en a un.
EDIT : en vérifiant cela, je trouve que d'autres ont également cru cela, mais personne n'est en mesure de trouver un tel soutien dans le projet de norme. Ce thread SO semble indiquer que la spécialisation partielle des modèles de fonctions n'est pas prise en charge dans C ++ 0x .
EDIT 2 : juste un exemple de ce que je voulais dire par "placer la fonction comme
static
membre d'une classe":#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 }
la source
Eh bien, vous ne pouvez vraiment pas faire de spécialisation partielle de fonction / méthode, mais vous pouvez effectuer une surcharge.
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){...}
C'est le chemin mais je ne sais pas si cela vous satisfait.
la source
En général, il n'est pas du tout recommandé de spécialiser les modèles de fonctions, en raison de problèmes de surcharge. Voici un bon article du Journal des utilisateurs C / C ++: http://www.gotw.ca/publications/mill17.htm
Et il contient une réponse honnête à votre question:
la source
Puisque vous pouvez partiellement spécialiser les classes, vous pouvez utiliser un foncteur:
#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 ; }
la source
()()
syntaxe laide .