Workaround for partial function specialization
In C++, functions (including members of classes) can be
templated as follows:
template<typename T, typename U> int f(T, U);
You can then specialise this, for example
template<> int f(int, int);template<> int f(int, double);
This allows you to write a different implementation for
different types. Unlike classes, partial specialization of functions is not
possible, so if you attempted something
template<typename U> int f(int, U);
then the compiler would complain. This is a limitation of
the C++ language, and the reason for this is because partial function
specialization is implemented at link-time.
However, the workaround is quite simple. You can do something like
template<typename T> struct overload { };
template<typename T, typename U> int f(T t, U u)
{
return f(overload<T>(), overload<U>(), t, u);
}
Then we can use standard (and less problematic) function
overloading to select different functions.
The compiler can happily select the correct overload between
template<typename U> int f(overload<int>, overload<U>, int t, U u);int f(overload<int>, overload<int>, int t, int u);int f(overload<int>, overload<double>, int t, double u);
The additional argument, overload<>, will be optimized
away by the compiler.
1 Comments:
I've spent a few minutes trying to "get" the point you're making.
I think I've found it but it seems quite far removed from the title and introduction. So let me just check whether I understood this.
Am I summarizing correctly that yuou made overload resolution more deterministic (and more selective) by introducing dependent arguments _that aren't susceptible to implicit conversions_?
This is indeed an under-appreciated idiom (or trick).
However, I hardly see any relation with partial specialization. I see only relation with overload resolution and implicit conversion rules. (I'd be happy to get a "safe C++ mode" that disallows all implicit conversions by default, but that's a whole different rant).
Cheers,
Seth
By Amber, at 5:51 pm
Post a Comment
<< Home