コンパイル時分岐
独自実装のintervalクラスでメンバ関数sin()を実装した。しかし、ジェネリックなコードが書きたい。 sin(x)とかいたとき、intervalならx.sin()を、でなければstd::sin(x)を呼び出したい。 こんなときどうすれば良い?
プライマリテンプレートと明示的特殊化を使って、コンパイル時に条件分岐を行えばよい。
#include <cmath>
#include <type_traits>
struct interval
{
    double sin( ) const
    {
        // unimplemented
        return 0.0 ;
    }
} ;
// プライマリーテンプレート
// デフォルトの実装
template < typename T >
struct dispatch
{
    static double invoke( T const & value )
    {
        return std::sin( value ) ;
    }
} ;
// interval型に対して明示的特殊化
template < >
struct dispatch<interval>
{
    static double invoke( interval const & value )
    {
        return value.sin() ;
    }
} ;
template < typename T >
void f( T const & x )
{
    double s = dispatch<T>::invoke(x) ;
}
int main()
{
    double d = 1.0 ;
    f( d ) ;
    
    interval i ;
    f( i ) ;
}
以下のように書くこともできる。
struct generic_sin
{
    template < typename T >
    static double invoke( T const & value )
    {
        return std::sin( value ) ;
    }
} ;
struct interval_sin
{
    static double invoke( interval const & value )
    {
        return value.sin() ;
    }
} ;
template < typename T >
using dispatch = std::conditional_t< std::is_same<T, interval>::value, 
    interval_sin, generic_sin > ;