2016-08-05 14 views
1

ジェネリックnum likeクラスを作成すると、関係するメンバー関数/演算子が存在することが重要になります。ジェネリックNumクラス

私はSFINAEを読んだことがありますが、正直ではありません。ここで

#include <iostream> 

template<typename T> 
class Numeric { 
    const T a; 
public: 
    Numeric(const T &v) : a(v) {} 

    T operator+(const Numeric<T> &b) { 
    return a + b.a; 
    } 
}; 

int main() { 
    Numeric<float> fl1(35.5); 
    Numeric<float> fl2(10.5); 
    Numeric<uint64_t> i64(10000); 
    std::cout << (i64 + fl1 + fl2) << std::endl; 
    return 0; 
} 

fl1 + fl2は大丈夫だと思うが、オペレータの定義が言うので、 Tfl1または fl2と混合することはできません同じタイプ i64です。 ここではテンプレートが正しいですか。たとえば、トップレベル Numを定義するオブジェクト階層を使用する方がよいでしょうか。すべての演算子を定義し、サポートされている各タイプのサブクラスを持っていますか?私はそれが混合タイプの問題を解決するとは思わないが。

EDIT 1:バリー/ lisyarusに解像度で 背景: 私はこのように定義された型を持つ古いコードベースを変更しています:

template<typename a> struct NumT : public SomeSuperType<a> { mp::cpp_int val;}; 

変更がネイティブのサポートを追加することですfloatdoubleのタイプはNumTタイプで可能な限り透明な方法で入力してください。 理想的には、NumTは宣言の変更を超えて変更するべきではありません。 valのタイプです。 既存のコードはa + bと他の算術演算はvalにあるだけで、既存のAPIを破壊することは重要ではありません。 i64 + fl1 + fl2 == 10046

+2

あなただけの 'T'によって解決されていない '数値'によって解決しようとしているだろうとは何ですか? – Barry

+5

あなたは正確に何を達成しようとしていますか?あるいは、 'i64 + fl1 + fl2'のタイプは何でしょうか? 'int64'でも' float'でも、それは損失です。 – lisyarus

答えて

2

がゆがんで取得することができ、それらを共通化しようとすると、数値型は(intfloatなど)が異なる理由があります。それにもかかわらず、std::common_typeを使用して、両方を含むことができるタイプを推測することができます。あなたには、いくつかの有効桁数を失うことになるdoubleに変換し、1434263462343574573ULLunsigned long longを持っている場合

マインドあなたは、例えば...ここ「精度」の喪失があるでしょう。

#include <iostream> 
#include <type_traits> 

template<typename T> 
class Numeric { 
    const T a; 
public: 
    Numeric(const T &v) : a(v) {} 
    T get() const { return a; } 
}; 

template<typename T, typename U> 
Numeric<typename std::common_type<T, U>::type> //With C++14, do std::common_type_t<T, U> 
operator + (const Numeric<T>& a, const Numeric<U>& b) { 
    return a.get() + b.get(); //Works because of the converting constructor 
} 

template<typename T> 
std::ostream& operator << (std::ostream& os, const Numeric<T>& n){ 
    os << n.get(); 
    return os; 
} 

int main() { 
    Numeric<float> fl1(35.5); 
    Numeric<float> fl2(10.5); 
    Numeric<uint64_t> i64(10000); 
    std::cout << (i64 + fl1 + fl2) << std::endl; 
    return 0; 
} 

この版画:

10046 
+0

私は、niceを参照してください。私は 'std :: common_type'について知らなかった。 – zcourts

+0

_「数値型がクラスにある理由がある」_これはどういう意味ですか? –

+0

@LightnessRacesinOrbit私は、異なる数値型(int、floatなど)がある理由を指摘しました。私は今、このステートメントに言い直しました。 – WhiZTiM

関連する問題