Eu sei que a especificação da linguagem proíbe a especialização parcial do template de função.
Eu gostaria de saber o motivo pelo qual isso proíbe? Eles não são úteis?
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) {}
tambémtemplate<> void f(int t, char u) {}
é permitido.Respostas:
AFAIK que mudou em C ++ 0x.Acho que foi apenas um descuido (considerando que você sempre pode obter o efeito de especialização parcial com um código mais detalhado, colocando a função como um
static
membro de uma classe).Você pode consultar o DR (Relatório de Defeito) relevante, se houver.
EDIT : verificando isso, descobri que outros também acreditaram nisso, mas ninguém é capaz de encontrar tal suporte no projeto de norma. Este encadeamento SO parece indicar que a especialização parcial de modelos de função não é compatível com C ++ 0x .
EDIT 2 : apenas um exemplo do que quero dizer com "colocar a função como um
static
membro de uma 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 }
fonte
Bem, você realmente não pode fazer especialização parcial de função / método, mas pode sobrecarregar.
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){...}
É o caminho mas não sei se te satisfaz.
fonte
Em geral, não é recomendado especializar modelos de função, devido a problemas com sobrecarga. Aqui está um bom artigo do C / C ++ Users Journal: http://www.gotw.ca/publications/mill17.htm
E contém uma resposta honesta à sua pergunta:
fonte
Como você pode especializar parcialmente as classes, pode usar um 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 ; }
fonte
()()
sintaxe feia .