General pattern specialization

I read Meyers book on efficient C ++ programming, in paragraph 25 I found total template specialization , but I can’t understand what this means? he also gives an example:

 namespace std { template<> void swap<Widget>(Widget& a, Widget& b) { swap(a.pimpl, b.pimpl); } } 

what does this operator mean: template<> (why without typename?)

early

+4
source share
2 answers

You usually use templates because you have a piece of code that is generic enough to be applied to different types. However, for some types you can do something else (for example, because there is a more efficient way to do this). This is when the help of the template comes to the rescue (you can think of them as "special case" templates):

For instance:

 class Foo {}; class Bar {}; // Primary template - the most generic. template<typename T, typename U> class MyClass { public: void DoSomething() { /* Performs the same generic operation for all T and U... */ } }; // Total specialization of the primary template template<> class MyClass<Foo, Bar> { public: void DoSomething() { /* ...Except when T is Foo and U is Bar. We may possibly do something different to allow for higher efficiency. */ } }; int main() { MyClass<int, char> a; // Uses the generic version of MyClass MyClass<Foo, Bar> b; // Uses the (total) template specialization } 

Please note that I use classes here, but the concept is the same. You can see that the same syntax is used for function templates.

For classes, however, there is such a thing as a partial specialized specialization, when not all parameters are fully specified in the template specialization. It might look like this:

 // Partial specialization #1 template<typename U> class MyClass<Foo, U> { public: void DoSomething() { /* ...Do something special when T is Foo. This code doesn't care what type U is. */ } }; template<typename T> class Baz {}; // Partial specialization #2 template<typename Z> class MyClass<Foo, Baz<Z> > { public: void DoSomething() { /* ...Do something special when T is Foo, and U is Baz. This code doesn't care what Baz gets for its template parameter. */ } }; int main() { MyClass<int, char> a; // Uses the generic version of MyClass MyClass<Foo, char> b; // Uses partial template specialization #1 MyClass<Foo, Baz<int> > c; // Uses partial template specialization #2 MyClass<Foo, Bar> d; // Uses the total template specialization } 

Please note that there is no ambiguity when working with these specializations, because the compiler selects the one that is best suited for the template parameters. By using these "special case" templates, we can create truly shared libraries.

Also note that this partial-focus business only works for classes, not functions! (You cannot partially specialize function templates). That is why your code fragment is written as it is - you can completely specialize function templates - something else is a function overload in the std (which prohibits the C ++ standard). I took the time to mention this because many people seem to be wrong.

 namespace std { /* Do **not** do this in the std namespace!!! You're not actually partially specializing the function, you're overloading the function in the std namespace which is prohibited by the C++ standard. */ template<typename T> void swap<Widget<T> >(Widget<T>& a, Widget<T>& b) {} } 
+11
source

Defines the implementation of the swap<T> function for the case when T is a Widget . This is a “general” specialization because it sets the types for all parameters of the swap<T> template (in this example there is only one).

You do this when your swap<Widget> implementation needs to do something different from the general swap<T> code.

The template<> tells the compiler that you are providing template specialization. There is nothing between <> because there are no template parameters to specify - the swap<Widget> defines all the parameters.

+1
source

All Articles