2013-05-02 7 views
11

enum classesの複合型を作成したいとします。私は小なり演算子をオーバーロードする必要がありますstd::map<>のようなSTLコンテナにObjectを使用するためには2つの列挙型クラスから複合型を作成すると、STLマップの準備ができます

enum class Color {RED, GREEN, BLUE}; 
enum class Shape {SQUARE, CIRCLE, TRIANGLE}; 

class Object { 
    Color color; 
    Shape shape; 
public: 
}; 

。しかし、1つの線形インデックスに両方の列挙型クラスを平坦化するために、私は何とか列挙型クラスの要素数(NOE)が必要です:

friend bool operator< (const Object &lhs, const Object &rhs) { 
    return NoE(Shape)*lhs.color+lhs.shape < NoE(Shape)*rhs.color+rhs.shape; 
} 

これは、同じ情報(要素の数)を入力せずに行うことができますどのようにプログラムの2つの場所で良い方法で? (いい方法は、FIRST_ELEMENT, LAST_ELEMENT、プリプロセッサの魔法などを意味しません)

質問(Number of elements in an enum)は、類似していますが、enum classesには該当しません。

この種の複合型をC++ 11で実装する最良の方法は何ですか。 enumクラスの定義は十分に強力ですか、それとも言う必要がありますか?

enum class Color {RED=0, GREEN=1, BLUE=2}; 
enum class Shape {SQUARE=0, CIRCLE=1, TRIANGLE=2}; 
+0

「enum」の状況は、C++ 11では変更されていません。 – syam

+0

なぜ平らにする必要がありますか?これは厳密な弱い順序付けを必要とするだけの 'std :: map'では必要条件ではありません。ネストされた比較で簡単に行うことができます。 – Chad

+0

'operator <'は 'map'のキーである場合にのみ必要です。値ではありません。それが鍵だと仮定すると、比較器で 'Color'か' Shape'優先順位を与えてみてはどうでしょうか?投稿された '演算子'よりもそれほど意味がありません。 – hmjd

答えて

15

をコメントし、既に他の人が述べたようにoperator<ShapeまたはColorのどちらかを優先し、最初がある場合にのみ、他の比較:あなたはそれがあまりにも素敵に見えるようにすることができ三元を使用して

等しい。 std::tieを使用してoperator<ための代替実装:「複合列挙型」

#include <tuple> 
friend bool operator<(const Object& lhs, const Object& rhs) 
{ 
    return std::tie(lhs.color, lhs.shape) < std::tie(rhs.color, rhs.shape); 
} 
+0

+1。私はちょうどこの答えを書こうとしていました! – juanchopanza

2

良い質問ですが、あなたが実際にがそれらを比較することColorの数を必要としない:

friend bool operator< (const Object &lhs, const Object &rhs) { 
    if(lhs.color > rhs.color) { 
     return false; 
    } 
    if(lhs.color < rhs.color) { 
     return true; 
    } 
    return lhs.shape < rhs.shape; 
} 
4

あなたは線形インデックスを必要としない、あなたは、単にそれらを比較することができます辞書順:

friend bool operator< (const Object &lhs, const Object &rhs) { 
    if (lhs.color < rhs.color) return true; 
    else if (lhs.color > rhs.color) return false; 
    else return lhs.shape < rhs.shape; 
} 
2

あなたが表現しようとしていることは、オブジェクトの順序を決定することです。色を確認し、色が同じ場合は形状を確認してください。それを線形化するのではなく、単純にブール演算子を使用します。

friend bool operator< (const Object &lhs, const Object &rhs) 
{ 
    return ((lhs.color < rhs.color) 
      || ((lhs.color == rhs.color) && (lhs.shape < rhs.color))) 
} 

EDIT:実際に、あなたもオブジェクト数の上限を使用することができ、動作は同じになります。

friend bool operator< (const Object &lhs, const Object &rhs) { 
    return 10000*lhs.color+lhs.shape < 10000*rhs.color+rhs.shape; 
} 

が、それは「マジックナンバー」(そうでないなどを紹介良いアイデア)。

2

shapeと比較する必要があるのは、colorが両方とも同じ場合のみです。 、

friend bool operator< (const Object &lhs, const Object &rhs) { 
    return lhs.color == rhs.color ? (lhs.shape < rhs.shape) 
            : (lhs.color < rhs.color); 
} 
7

は単にstd::tuple<Color, Shape>としての使用を検討してくださいこれは、辞書の順序付けを使用して、あなたのために既に定義されている比較演算子を伴います。たとえば、有効なコード:

bool b = std::make_tuple(Color::RED, Shape::CIRCLE) 
     < std::make_tuple(Color::GREEN, Shape::SQUARE); 
関連する問題