2011-09-02 7 views
10

通常の関数のオーバーロードがこの例の方が効果的であるという事実を簡単に却下します。これは、テンプレートプログラミングについて学ぶ方法としてのみ意味されています。関数のオーバーロードを使用することで得られる利点/相違点については、関数テンプレートの特殊化と比較してコメントすることは大歓迎です(しかし、それは独自の質問に値するかもしれません)。テンプレートの特殊化のために複数の型を一致させる

template <typename T> 
inline void ToString(T value, char* target, size_t max_size); 

template <> 
inline void ToString<float>(float value, char* target, size_t max_size) 
{ 
    snprintf(target , max_size , "%f" , value); 
} 

template <> 
inline void ToString<double>(double value, char* target, size_t max_size) 
{ 
    snprintf(target , max_size , "%f" , value); 
} 

のみ両方floatdouble型と一致これらの専門分野のいずれかを記述する方法があります:


は、次の例を考えてみましょうか?

基本的には、floatdouble(「浮動小数点型」または「倍精度型」)の両方に一致するテンプレートタイプのテンプレート特殊化を作成することを想定していますが、C++で可能かどうかはわかりません。それは、私が予期せぬテンプレートマジックが私の目の前で起こっているのを見たので、ここで質問するのは良い質問だと思います。

+1

複数の具体的なタイプに一致するものが必要な場合は、部分的な特殊化ですが、これは機能には使用できません。 –

+0

こんにちは@Kerrek、私の部分的な専門化の理解は、テンプレートパラメータのサブセットを特化することです。ここには1つのテンプレートパラメータしかありません。私は部分的な専門化がここでどのように関連しているかに従いません – lurscher

+2

部分的な専門化は、結果がまだタイプではなくテンプレートであることを意味します。たとえば、 'template struct X;テンプレート構造体X ; 'それは部分的です。 –

答えて

5

ここでは標準溶液のイディオムです:

#include <type_traits> 
#include <cstdio> 


// Helper class 

template <typename T> 
struct Printer 
{ 
    static typename std::enable_if<std::is_floating_point<T>::value, int>::type 
    print(T x, char * out, std::size_t n) 
    { 
    return std::snprintf(out, n, "%f", x); 
    } 
}; 

// Convenience function wrapper 

template <typename T> int print(T x, char * out, std::size_t n) 
{ 
    return Printer<T>::print(x, out, n); 
} 

void f() 
{ 
    char a[10]; 

    Printer<double>::print(1.2, a, 10); // use helper class 
    print(1.4f, a, 10);     // wrapper deduces type for you 
} 

あなたは非フローティング方式で建設のいずれかを呼び出す場合は、コンパイル時にエラーが発生します。しかし、これは長い倍精度の場合に誤って機能するかもしれないことに注意してください。%Lfフォーマット指定子が必要です。また、可変引数関数の引数を渡すと浮動小数点数が倍に昇格することを思い出してください。

+0

ああ、std :: type_traitsについて知りませんでした、ありがとう! – lurscher

関連する問題