2013-07-23 1 views
6

私はすでにオペレータ>オペレータ定義さ<(と演算子==)を持っている場合は、私が演算子> =オペレータ< =を定義する必要があります、またはコンパイラが私のためにそれらを宣言します私が意図的に宣言していないとしたら?私は演算子==が定義されている場合にも> =と<=演算子を手動で宣言する必要はありますか?

、コンパイラは私のために演算子!=を宣言しますか?

+2

あなたなら、私は私の一般的なユーティリティで#defineが、それはこのように書き含める必要があり

'operator'と 'operator =='が定義されている場合は、['std :: rel_ops'](http://en.cppreference.com/w/cpp/utility/rel_ops/operator_cmp)名前空間にドラッグしてオペレータの残りの部分は、これは実際には良いソリューションではありません(http://stackoverflow.com/questions/62 25375/idiomatic-of-stdrel-ops)。 [Boost.Operators](http://stackoverflow.com/a/14756785/241631)はこれを行う正しい方法です。 – Praetorian

+0

何人かの演算子の入力を節約するために、継承を使って何かが私の右に座っていません。むしろそれらを手動で追加しますか? =) –

+0

この機能を提供するクラスから派生したものは、素晴らしい文書値を持っています。コンセプトの原始的な形です。 – TemplateRex

答えて

6

いいえ、コンパイラは、手動で定義しなかった演算子を宣言/定義しません。しかし、Boost.Operatorsが好きかもしれません。コンパイラがやりたいことをまさに実行します。

+0

Dang。まともなデフォルトのコピーコンストラクタなどを生成します。単純な自動生成演算子を期待していました!=(other){return!(* ​​this == other); } *。ああ、答えに感謝!それを受け入れる前にちょっと待ってください。 –

+1

+1 Boost.Operators(Daniel Frey)のメンテナーは、そのライブラリの[df.operators](https://github.com/d-frey/operators)という非公開ポートをC++ 11に持っています(rvalue overloadsとnoexcept) – TemplateRex

5

コンパイラはここであなたのために何自体をしないだろうが、それは から適切なクラスを継承することで自動的に生成することが 比較的簡単だ、のようなもの:

template< typename DerivedType > 
class ComparisonOperators 
{ 
public: 

    friend bool   operator!=( 
          DerivedType const& lhs, 
          DerivedType const& rhs) 
    { 
     return !(lhs == rhs); 
    } 

    friend bool   operator<=( 
          DerivedType const& lhs, 
          DerivedType const& rhs) 
    { 
     return !(rhs < lhs); 
    } 

    friend bool   operator>( 
          DerivedType const& lhs, 
          DerivedType const& rhs) 
    { 
     return rhs < lhs; 
    } 

    friend bool   operator>=( 
          DerivedType const& lhs, 
          DerivedType const& rhs) 
    { 
     return !(lhs < rhs); 
    } 

protected: 
         ~ComparisonOperators() {} 
} ; 

は、あなたのクラスで<==を定義します

class MyClass : public ComparisonOperators<MyClass> 
{ 
    // ... 
public: 
    bool operator==(MyClass const& other) const; 
    bool operator<(MyClass const& other) const; 
    // ... 
}; 

だけ注意を:あなたは、オペレータのすべてを取得します これから派生する、と私は手動で私はACTUバージョンを簡素化しました同様==<を定義ら使用、 は、メンバ関数 compareisEqual探し、およびNO isEqualがない場合==!=ためcompareを使用します。 はエラーが発生したとは思わないが、わからない。

+0

私は、負の値、正の値、または0の値(伝統的なCのアプローチ)を返す 'int compare(DerivedType const&o)'を好む傾向があります。通常、 '=='と '<'は非常によく似たコードなので、それらをマージするといいです。 –

+3

Boost.Operatorsがすでにあなたのためにしていることはまったくそうではありませんか? ;-) –

+0

@ edA-qamort-ora-yはい。それは上記の 'compare'のシグネチャです。規則は:等価性のための比較だけです: 'isEqual'(そしてそれらが使われていれば関係演算子はコンパイルに失敗します)。等価性と関係性、 'compare'を使います。 _if_等価性ははるかに速く実行でき、次に両方を提供することができます。そして、正しいものを呼び出す 'ComparisonOperators'クラスには、少しのメタプログラミングがあります。 –

0

ここでは、boostと継承を使用していくつかの良い回答があります。しかし、誰かが指摘したように - 演算子の作成に継承を使用すると間違っているようです。

私は#defineがC++の「タブー」だと知っていますが、それでも私がここで使用しています。

#define CREATE_COMPARITORS(name)        \ 
inline bool operator>(const name &o){return o<*this;}   \ 
inline bool operator<=(const name &o){return not (o<*this);} \ 
inline bool operator>=(const name &o){return not (*this<o);} \ 
inline bool operator!=(const name &o){return not (*this==o);} 

私はクラスを持っている場合、その後、私は宣言する必要があるすべてはoperator<operator==です::

class ttt{ 
    //... 
    bool operator<(const ttt &o); 
    bool operator==(const ttt &o); 
    CREATE_COMPARITORS(ttt); 
    //... 
}; 
+0

あなたは、 ... 違う。"今のところ、私はあなたの不当な意見よりもブースターのライブラリデザイナーを信頼しています。 – djechlin

+0

このスレッドの他の誰かから引用されています。「何人かの演算子を入力しなくても、何かが継承を使って私のところに座っていません。今、私の答えが役に立たなかったので、あなたが私をdownvoteしたい場合、または何もしないでください。しかし、あなたが 'Boost'が好きではない大勢のグループの一人で、それがどうやってどうやっているのか、' Boost'が好きな別のグループの一員になってしまったので、あなたの力を乱用する。 – rabensky

+0

-1 #define over継承を使用することを推奨しています。継承に何が間違っているのか、またはこのコードがマクロの通常の問題から免除されている理由は正当です。 – djechlin

関連する問題