C ++ - What is the purpose of specializing function templates? When to use it?

Learning C ++ came across functional patterns. The chapter mentions specialized specialization.

  • template <> void foo<int>(int);

  • void foo( int );

Why specialize when you can use the second? I thought the templates were supposed to be generalized. What is the point of specializing a function for a particular data type when you can just use a regular function?

Obviously, template specialization exists for some reason. When should you use it? I read Sutter "Why not specialize ..." , but I need a more informal version, since I'm just learning this stuff.

+5
source share
6

, , templated .

, , , , .

, ( , ), , , :

template <typename T> void f(T) { 
   std::cout << "generic" << std::endl; 
}
void f(int) { 
   std::cout << "f(int)" << std::endl; 
}
int main() {
   int x = 0;
   double d = 0.0;
   f(d); // generic
   f(x); // f(int)
   f<int>(x); // generic !! maybe not what you want
   f<int>(d); // generic (same as above)
}

int , , .

+11

. , , , ( , , ).

Herb Sutter ?, , .

+4

, , .

template<typename T>
void MySwap(T& lhs, T& rhs)
{
    T tmp(lhs);
    lhs  = rhs;
    rhs  = tmp;
}

, . , std::vector swap().

template<>
void MySwap(std::vector<int>& lhs,std::vector<int>& rhs)
{
    lhs.swap(rhs);
}

, std:: swap, . , , MySwap() , . , .

.

void MySwap(std::vector<int>& lhs,std::vector<int>& rhs)
{
    lhs.swap(rhs);
}

, , ( ). . . , ( , , , ). . , .

+1

. , . , . , (int, short, float) , . serialize/unserialize, , serialize/unserialize , .

0

. , . , . , ( ).

, std::swap , , std::swap, swap, <algorithm> ::std::swap( a, b );. , : "" , .

. , . (, -.) , , , , .

ADL , .

0

One case for template specialization that is not possible with overloading is template metaprogramming. Below is the actual code from the library that provides some of these services at compile time.

namespace internal{namespace os{
    template <class Os> std::ostream& get();

    struct stdout{};
    struct stderr{};

    template <> inline std::ostream& get<stdout>() { return std::cout; }
    template <> inline std::ostream& get<stderr>() { return std::cerr; }
}}

// define a specialization for os::get()
#define DEFINE_FILE(ofs_name,filename)\
    namespace internal{namespace os{                        \
        struct ofs_name{                                    \
            std::ofstream ofs;                              \
            ofs_name(){ ofs.open(filename);}                        \
            ~ofs_name(){ ofs.close(); delete this; }                    \
        };                                          \
        template <> inline std::ostream& get<ofs_name>(){ return (new ofs_name())->ofs; }   \
    }}                                              \
    using internal::os::ofs_name;   
-1
source

All Articles