Wiem, że specyfikacja języka zabrania częściowej specjalizacji szablonu funkcji.
Chciałbym poznać uzasadnienie, dlaczego tego zabrania? Czy nie są przydatne?
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) {}
teżtemplate<> void f(int t, char u) {}
jest dozwolone.Odpowiedzi:
AFAIK, który został zmieniony w C ++ 0x.Myślę, że to tylko przeoczenie (biorąc pod uwagę, że zawsze można uzyskać częściowy efekt specjalizacji za pomocą bardziej rozwlekłego kodu, umieszczając funkcję jako
static
członek klasy).Możesz poszukać odpowiedniego DR (raport defektu), jeśli taki istnieje.
EDYCJA : sprawdzając to, stwierdzam, że inni też w to uwierzyli, ale nikt nie jest w stanie znaleźć takiego wsparcia w projekcie normy. Ten wątek SO wydaje się wskazywać, że częściowa specjalizacja szablonów funkcji nie jest obsługiwana w C ++ 0x .
EDYCJA 2 : tylko przykład tego, co miałem na myśli przez „umieszczanie funkcji jako
static
członka klasy”:#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 }
źródło
Cóż, naprawdę nie możesz zrobić częściowej specjalizacji funkcji / metod, ale możesz wykonać przeciążenie.
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){...}
Taka jest droga, ale nie wiem, czy cię to satysfakcjonuje.
źródło
Generalnie nie zaleca się w ogóle specjalizowania szablonów funkcji ze względu na problemy z przeciążeniem. Oto dobry artykuł z dziennika użytkowników C / C ++: http://www.gotw.ca/publications/mill17.htm
I zawiera uczciwą odpowiedź na Twoje pytanie:
źródło
Ponieważ możesz częściowo specjalizować się w klasach, możesz użyć funktora:
#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 ; }
źródło
()()
składni.