2017-01-14 17 views
4

構造体のstl :: setを作成する必要があります。私はstd :: set構造体の作成方法

stl::set <Point> mySet; //Point - name of structure 

を書くしかし、私は

Point myPoint; 
mySet.insert(myPoint); 

は、いくつかのコンパイルエラー(エラーC2784、C2676エラー)があるマイセットする構造のインスタンスを追加してみてください。 誰かが助言を与えることができますか?

1> C:\プログラムファイルのMicrosoftのVisual Studio 10.0 \ VC \含める\ xfunctional(125)\(x86の):エラーC2784:ブールのstd ::演算子<(のconstのstd ::ベクトル< _Ty、_Ax > &、constのはstd ::ベクトル< _Ty、_Ax> &):テンプレートに引数を持って来ることができなかった "のconstのstd ::ベクトル< _Ty、_Ax> &" "constのポイント"

1> Cから: \ Program Files(x86)\ Microsoft Visual Studio 10.0 \ VC \ include \ xfunctional(125):エラーC2676:バイナリ "<": "const Point"は、この演算子またはintegrateで受け入れ可能な型への変換を定義していませんd演算子

+0

これは 'std :: set'です。 'C2784'と' C2676'は意味をなさない。実際のメッセージが必要です。また、 'struct Point'が' operator <'を実装していることを確認しましたか? 'std :: set'はそれを必要とします。 – DeiDei

+1

'Point'構造体の '演算子<'を定義します。 – void

答えて

7

std::setテンプレートは、一意のオブジェクトのソートされたセットを含む連想型コンテナを提供します。キーワードはで、は一意のです。並べ替えをサポートするには、さまざまな可能性がありますが、最終的にはすべてがstrict weak orderingに準拠する必要があります。

std::setの2番目のテンプレート引数は、の比較タイプです。デフォルトのstd::less<Key>は、標準ライブラリから提供されます。Keyは、コンテナに格納するオブジェクトのタイプです(ケースでは、Point)。このデフォルトでは、キータイプをサポートする任意の許容operator <を使用して単純に比較を生成します。これはデフォルトのコンパレータ(あなたのケースでstd::less<Point>)を使用している場合は、あなたのクラスは、このような操作を想定しなければならない、一つの方法または別のことを意味します。以下に表示され、これを行うための

Point pt1(args); 
Point pt2(args); 

if (pt1 < pt2) // <<=== this operation 
    dosomething(); 

複数のメソッド:

は、これを実現する最も簡単な方法は、あなたのPointクラスのメンバーoperator <を提供することで圧倒的にメンバーoperator <

を提供します。その際、pt1 < pt2が有効になり、std::less<Point>が満足しています。あなたのクラスを想定すると、従来のX、Y点であり、それは次のようになります。

struct Point 
{ 
    int x,y; 

    // compare for order.  
    bool operator <(const Point& pt) const 
    { 
     return (x < pt.x) || ((!(pt.x < x)) && (y < pt.y)); 
    } 
}; 

は、もう一つの方法は、カスタムコンパレータの種類を提供することでカスタムコンパレータタイプ

を提供するのではなくstd::less<Point>に依存しています。これの最大の利点は、さまざまなことを意味するいくつかを定義し、必要に応じてコンテナやアルゴリズムで使用できることです。このアプローチを検討する

std::set<Point,CmpPoint> mySet; 

何か:それと

struct CmpPoint 
{ 
    bool operator()(const Point& lhs, const Point& rhs) const 
    { 
     return (lhs.x < rhs.x) || ((!(rhs.x < lhs.x)) && (lhs.y < rhs.y)); 
    } 
}; 

、あなたは今、このようなあなたのstd::setを宣言することができますタイプは、プライベートメンバ変数や関数へので、任意のアクセスPointの一部ではありません能力を盛り立てて説明する必要があります。


はフリー機能operator <

に単にoperator <を提供グローバルフリー機能を提供しているもう一つのあまり共通のメカニズムを提供します。これはメンバ関数ではありません。これを繰り返すと、デフォルトのstd::less<Point>が有効なコードになります。

bool operator <(const Point& lhs, const Point& rhs) 
{ 
    return (lhs.x < rhs.x) || ((!(rhs.x < lhs.x)) && (lhs.y < rhs.y)); 
} 

これは、カスタムコンパレータとメンバーオペレータの両方が混在しているように見えますが、実際にはそれぞれの長所と短所の多くが出てきます。例:メンバーoperator <のように、デフォルトのstd::less<Point>を使用することができます。カスタムコンパレータと同様、これはクラス以外の関数なので、プライベートメンバーへのアクセスはfriendingまたはaccessorを介して提供する必要があります。


概要

ニーズのために、私は単純なアプローチで行くと思います。メンバーを作るだけですoperator <。あなたはいつもあなたのPointをそのように注文している可能性があります。そうでない場合は、カスタムコンパレータを使用してください。 のいずれかケースを作る厳しい弱い秩序を守る。

関連する問題