I'm reading the book of Meyers about effective c++ programming, in item 25 I found total template specialization
, but I can't understand it, what does that it mean? he also gives example:
namespace std {
template<>
void swap<Widget>(Widget& a, Widget& b)
{
swap(a.pimpl, b.pimpl);
}
}
what does this statement mean : template<>
(why without typename?)
thanks in advance
The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.
There are three kinds of templates: function templates, class templates and, since C++14, variable templates. Since C++11, templates may be either variadic or non-variadic; in earlier versions of C++ they are always non-variadic.
Explicit (full) specializationAllows customizing the template code for a given set of template arguments.
How many types of specialization are there in c++? Explanation: There are two types of specialization. They are full specialization and partial specialization.
Typically you use templates because you have a piece of code that is generic enough that it can be applied to different types. However, for some types you may want to do something different (e.g. because there's a more efficient way of doing it). This is when template specialization comes to the rescue (you can think of them as "special case" templates):
For example:
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
}
Note that I'm using classes here, but the concept is the same. You can see that a similar syntax applies for function templates.
For classes, though, there is such a thing as partial template specialization, when not all the parameters are completely 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
}
Note that there's no ambiguity when dealing with these specializations because the compiler picks the one that is the best fit for the template parameters. By allowing for these "special case" templates, we can create truly generic libraries.
Also note that this partial specialization business only works for classes, not functions! (You can't partially specialize function templates). That's why your code snippet is written the way it is - you can only totally specialize function templates - anything else is function overloading in the std
namespace (which the C++ standard disallows). I took the time to mention this because lots of people seem to get this 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) {}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With