2016-10-04 4 views
1

は、私たちがカスタムクラスにoperator/があるとします。テンプレートオペレータの実装を選択し

struct my_class { 
    uint64_t value; 
} 

template<class T> 
constexpr T operator/(const my_class& a, const my_class& b) 
{ 
    return static_cast<T>(a.value)/static_cast<T>(b.value); 
} 

方法1は、例えば、intまたはdoubleを返すために(abmy_class型である場合)a/bを選択することができますか? 、特定のオペレータテンプレートを選択するには、関数としてそれを呼び出す必要があります

+0

何を基準に選択しますか? –

+0

'constexpr T operator /'を 'constexpr int operator /'に変更しますか? –

+0

@appleapple時には 'double'を取得したいときに' int'を取得することがあります。 – vladon

答えて

2

auto result = operator/<double>(my_class{4}, my_class{2}); 
// result is 2.0 
+0

ええ、それは悪いです。結果を受け入れる変数のタイプに基づいて選択できますか?私。 'int result = a/b'は' int'を返しますが、 'double result = a/b'はdoubleを返しますか? – vladon

+0

@vladonいいえ、あなたはできません – bolov

+1

@vladonあなたができることは、プロキシクラスを使った怠惰な評価です。しかし、あまりにも多くの仕事です – bolov

5

あなたは可能性があり、テンプレートの魔法と変換演算子のビットを持ちます。オペレータは、このように行うことができます過負荷を、次に

struct DivideMyClass { 
    DivideMyClass(const MyClass& lhs_, const MyClass& rhs_) : lhs{lhs_}, rhs_{rhs} {} 

    template<typename T> 
    operator T() const { 
     return static_cast<T>(lhs.value)/static_cast<T>(rhs.value); 
    } 

private: 
    const MyClass& lhs; 
    const MyClass& rhs; 
}; 

:あなたは最初にあなたの発現のための単純なラッパーを定義することができ

constexpr DivideMyClass operator/(const my_class& a, const my_class& b) 
{ 
    return DivideMyClass{a, b}; 
} 

次に、あなたのコードは次のようになります。

double d = MyClass{21}/MyClass{5}; // will be equal to 4.2 

この解決方法が悪い理由

言語は戻り値の型によって過負荷になっていません。コードでは、バグがあると思う他の人を混乱させます。このメソッドを広範囲に使用すると、解読不可能なコードになります。

もう1つのことは、暗黙のうちに変換が行われ、実際に通話サイトのオペレータで変換が行われたかどうかはわかりません。

あなたはAAA idom(ほとんど常にAutoを使用します)を防止します。 autoがあなたのコードを壊すかもしれません。それは悪いことです。

このような手法は、テンプレートの表現やそのようなものに使用する必要があります。単純な分割のためにそれを使用すると、他のものを混乱させます。

+2

noooooooo .... 1分前...より良い... [sigh] – bolov

+0

プロキシクラス 'template 'で書くと 'auto'は動作しますか? – vladon

+0

いいえ、Autoでは変換は行われません。 Autoは、 '='に続く式の型を推論します。 –

3

結果を受け入れる変数のタイプに基づいて選択できますか?私。 int result = a/bはintを返しますが、double result = a/bはdoubleを返しますか?

あなたがこれを行うことで地獄に屈していれば、それは複雑ですが、私はそれをお勧めしません。利点を重視しなければならず、導入した複雑さを慎重にしなければなりません。遅延評価でこれを行うことができます:

struct X { 
    int value; 
}; 

struct X_op_proxy { 
    const X& lhs; 
    const X& rhs; 

    template <class T> 
    operator T() const { return static_cast<T>(lhs.value)/static_cast<T>(rhs.value); } 
}; 
auto operator/(const X& lhs, const X& rhs) -> X_op_proxy 
{ 
    return {lhs, rhs}; 
} 

int main() 
{ 
    X x1{11}, x2{2}; 

    int i = x1/x2; 
    cout << i << endl; 

    float f = x1/x2; 
    cout << f << endl; 
} 

これは最小限であるため、この技術の概要を知ることができます。あなたはそれを適応させ、必要に応じて成長させることができます。

+0

うわー!すばらしいです!私はそれが不可能だと思った:-)だからこそ私は愚かな(最初のビューで)ここに質問している:-)ありがとう! – vladon

+0

単純に 'X_op_proxy operator /(const X&lhs、const X&rhs)'はなぜですか? –

+0

@ W.F。代わりの構文だけは問題ではありません。 – vladon

関連する問題