2016-10-17 33 views
0

私はC++関数を使い、関数のオーバーロードを利用するC++テンプレート関数を書きたいと思っています。複数のC関数を内部的に呼び出すためのC++テンプレート関数の記述方法?

例えば、Iは、入力パラメータの種類に基づいて、fabs又はmath.hで定義さabsへの適切な呼び出しを行うテンプレートを使用して機能myAbsを作成する必要があります。これを行う方法?

#include <math.h> 
template<typename T> 
T abs(T x) 
{ 
    // I need to write an efficient code here! 
    // If it is 'double' and 'float' I may be able to compare the  
    // sizeof(Type) and call 'return fabs(x)' or 'return abs(x)'. 
    // But this is not a good solution as two types can be of same size! 

} 

注:私は単に例として私の質問を説明するために使用しました。私はすでに、そのような関数「abs」が既に<cmath>にあることを知っています。助け

#include <math.h> 
#include <type_traits> 
template<typename T> 
T abs(T x) 
{ 
    if(std::is_same<T,double>::value) 
    { 
     //do double stuff 
    } 
    else if(std::is_same<T,float>::value) 
    { 
     //do float stuff 
    } 
    else 
    { 
     //deal with unsupported type 
    } 
} 

希望:

+0

なぜ 'cmath'ではなく' math.h'をインクルードしていますか? –

+0

@AndrewHenle:私はすでに記事の最後に、これは単なる例であるというメモとして述べました! – user4661268

答えて

0

あなたはC++ 11種類の特徴を使用することができます。

+1

本当にありません。 2つの 'std :: string'を取る' abs'関数があり、 'abs'関数でその分岐を作ると、' abs'へのすべての呼び出しは失敗します。 – Rakete1111

+0

@ Rakete1111タイプの控除が失敗することを示唆していますか?次に、型を明示的に指定します。 –

+0

「コンパイル時間チェック」は、初心者に誤解を招く可能性があります(コンパイル時にブランチが作成されたように聞こえることがあります)。それを "あなたはC++ 11タイプの形質を使うことができます"に変更することを検討してください。 –

0

明示的関数テンプレートを特化することができます

template<> 
double abs<double>(double x) { 
    return fabs(x); 
} 

あなたはより多くをoverengineerしたい場合は、繰り返しを削減し、タグ選択でそれを補うために、タグ・ディスパッチを採用することができます。分岐がコンパイル時に取られることを保証(ほとんどはちょうど楽しみのために)

4

C++ 17ソリューション、:

template <typename T> 
T my_abs(T x) 
{ 
    if constexpr(std::is_same<T, double>{}) 
    { 
     return std::fabs(x); 
    } 
    else if constexpr(std::is_same<T, float>{}) 
    { 
     return std::abs(x); 
    } 
    else 
    { 
     // Produces a compiler error: 
     struct invalid_type; 
     return invalid_type{}; 
    } 
} 

on wandbox

+0

static_assert(false、 "無効なタイプ");のようなものが私の目には少し良く見えます。 – DeiDei

+0

@DeiDei:wandboxで試してください:) –

5

テンプレートは、ここでの答えではないかもしれません。

inline float myAbs(float x) { return fabsf(x); } 
inline double myAbs(double x) { return fabs(x); } 
+2

あいまいなオーバーロードに気を付けてください。 http://stackoverflow.com/questions/1374037/ambiguous-overload-call-to-absdoubleを参照してください。 –

関連する問題