Programming

Wednesday, January 15, 2014

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 Blogger Amber, at 5:51 pm  

Post a Comment

<< Home