11

2 つの から複合型を作成したいと思いますenum classes

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

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

ObjectSTL コンテナーで使用するにstd::map<>は、less-than 演算子をオーバーロードする必要があります。ただし、両方の列挙型クラスを 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 つの場所に同じ情報 (要素の数) を適切な方法で入力せずに、これを行うにはどうすればよいでしょうか? (良い方法は no FIRST_ELEMENT, LAST_ELEMENT、プリプロセッサ マジックなどを意味します)

質問 (列挙型の要素数) は似ていますが、対処していませんenum classes

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

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

6 に答える 6

15

Shapeコメントされ、他の人がすでに述べたように、どちらかColorを優先しoperator<、最初が等しい場合にのみ他方を比較します。operator<を使用するための代替実装std::tie:

#include <tuple>
friend bool operator<(const Object& lhs, const Object& rhs)
{
    return std::tie(lhs.color, lhs.shape) < std::tie(rhs.color, rhs.shape);
}
于 2013-05-02T14:43:11.893 に答える
7

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

bool b = std::make_tuple(Color::RED, Shape::CIRCLE)
       < std::make_tuple(Color::GREEN, Shape::SQUARE);
于 2013-05-02T14:53:54.040 に答える
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;
}
于 2013-05-02T14:33:36.987 に答える
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;
}
于 2013-05-02T14:33:24.187 に答える
2

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

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

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

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

しかし、それは「マジックナンバー」を導入します(あまり良い考えではありません)。

于 2013-05-02T14:33:54.503 に答える
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);
}
于 2013-05-02T14:36:41.563 に答える