wajed
wajed

Reputation: 523

When is "explicit specialization" needed or desirable in C++?

I'm reading

Primer C++ > Adventures in Functions > Templates > Explicit Specialization.

To show the reason/use for Explicit Specialization, a case is illustrated:

Consider a swap template function that can swap any type (int, double, struct etc...)

But there is a specific struct job that you want to only swap two members of, and leave the rest of the members as they are. You will need a different definition, and so you will have to make an Explicit Specialization.

There is this statement in the same section:-

"A specialization overrides the regular template, and a non-template function overrides both."

Why not just make a regular function for that use? Then a regular/non-template will override the template, isn't it?

If my solution is correct, then what is a good example for Explicit Specialization?

Upvotes: 8

Views: 4737

Answers (4)

Zack Light
Zack Light

Reputation: 324

Another usage is to mark a special case of templated function as not callable.

template<typename T>
void processPointer(T* ptr);
template<>
void processPointer<void>(void*) = delete;
template<>
void processPointer<char>(char*) = delete;

(From Effective Modern C++)

Upvotes: 0

iammilind
iammilind

Reputation: 69988

One of the use case for explicit specialization is to avoid regular function to be skipped when some changes happens in the actual template function. To understand see below example:

template<typename T1, typename T2>
void foo(T1 o1, T2 o2)  // template function
{}
void foo(int o1, int o2) // regular function overloaded
{}

Till now it's fine. Now after sometime you got to change the definition of template<> foo()

template<typename T1, typename T2, typename T3> // new parameter added
void foo(T1 o1, T2 o2, T3 o3)  // template function
{}

You changed all the calls to foo() accordingly, but you missed/messed to change the regular overloaded function foo(). Then, it's a disaster ! Because compilation would go fine and regular calls would be silently replaced by the template<> foo(), which is undesired.

Now, had there been an explicit specialization such as,

template<>
void foo(int o1, int o2) // explicit specialization
{}

then that function will give you compilation error due to unmatched parameters and which would remind you of corresponding changes.

The other usage or (difference) is that an explicitly specialized function can be included in header file without any concern of multiple symbol linking error. Note that, explicit specialization has its own drabacks also, but I have demo a good side of it.

Upvotes: 12

Puppy
Puppy

Reputation: 146910

Standard functions may be specialized but may not be overloaded, just for one example. Another example would be where the types are non-deducible and you have existing code which calls them with explicit template arguments- your overload is worthless then.

Upvotes: 2

Serge Dundich
Serge Dundich

Reputation: 4429

Why not just make a (regular) function for that use? Then a regular/non-template will override the template?

Of course you can use regular function overload instead of explicit function template specialization if it is OK for you. But regular function overload will not be used if you explicitly use function template (by specifying template parameters).

Example:

You have function template:

template< class T >
void foo( T& x, const T& y )
{
...
}

Then if you specify function overload:

void foo( double& x, const double& y )
{
....
}

In the code like this:

template< class T >
void some_function( T& x )
{
    T y;
    ......
    foo<T>( x, y );
}

function overload void foo( double& x, const double& y ) will never be used.

But if you specify function template specialization

template<>
void foo<double>( double& x, const double& y )
{
....
}

Then some_function would use your specialization if you call

double x;

some_function(x);

somewhere.

Upvotes: 0

Related Questions