7

STLを使用してintキーでソートしておきたいクラスAへのポインターのベクトルがあります。これを行うためにoperator <、クラス A でを定義しました

bool operator< (const A &lhs, const A &rhs){
    return (lhs.key < rhs.key);
};

私の挿入機能では、次のようになります

vector<A*>::iterator it = lower_bound(vec.begin(), vec.end(), element);
vec.insert(it, element);

lower_bound新しい要素を配置できる最初の場所を返すことを期待していますが、機能しません。キー 0、1、2、3 を持つ A オブジェクトを挿入すると、ベクターの順序が正しくありません (2、3、1、0)。何故ですか ?

おそらく、このオブジェクトにコンパレーターを使用することもできます。

upper_bound / lower_bound の比較関数

しかし、私のコードの何が問題になっていますか?

4

2 に答える 2

6

あなたの例から、ポインターのベクトルを使用しています: std::vector<A*>. したがって、に渡すポインターの比較を定義する必要がありますstd::lower_bound

bool less_A_pointer (const A* lhs, const A* rhs)
{
    return (lhs->key < rhs->key);
}

auto it = std::lower_bound(vec.begin(), vec.end(), element, less_A_pointer);
//...

もちろん、問題はそもそもなぜポインターを使用するのかということAです。本当に必要でない限り、オブジェクトを格納するだけです。ポインターを保存する必要がある場合は、 std::shared_ptrこれを処理するものを調べてください。

std::vector<std::shared_ptr<A>> v;
std::shared_ptr<A> element(new A(...));
auto it = std::lower_bound(v.begin(), v.end(), element); //Will work properly

フリー関数を書く代わりにラムダを使うこともできます:

auto it = std::lower_bound(v.begin(), v.end(), 
                          [](const A* lhs, const A* rhs)
                          { return lhs->key < rhs->key; });
于 2013-05-06T09:12:17.270 に答える
1

本当にのポインターが必要な場合は、 のようなスマート ポインターstd::vectorの使用を検討することをお勧めします。生のポインターは、ポインターを監視している場合は問題ありませんが、通常は生の所有ポインターを使用しないでください (特別な条件がない限り)。std::shared_ptr

ラムダをstd::lower_bound()に渡して、並べ替え基準を指定できます (この場合、主要なデータ メンバーを比較します)。

std::vector<std::shared_ptr<A>>::iteratorさらに、の戻り値を明示的に記述する代わりに、std::lower_bound()C++11 のキーワードを使用することもできますauto。これにより、この場合、コードが読みやすくなります。

コンパイル可能なコード サンプルは次のとおりです (g++ 4.8.0 でコンパイル)。

#include <algorithm>    // for std::lower_bound
#include <iostream>     // for console output
#include <memory>       // for std::make_shared, std::shared_ptr
#include <string>       // for std::string
#include <vector>       // for std::vector
using namespace std;

// Test data structure
struct A
{
    int Key;
    string Data;

    A()
        : Key(0)
    {}

    A(int key, const string& data)
        : Key(key), Data(data)
    {}
};

ostream& operator<<(ostream& os, const A& a)
{
    os << "(key=" << a.Key << ", data=\"" << a.Data << "\")";
    return os;
}

void Print(const vector<shared_ptr<A>> & v)
{
    cout << "[ ";
    for (const auto & p : v)
    {
        cout << *p << " ";
    }
    cout << " ]\n";
}

int main()
{
    // Test container
    vector<shared_ptr<A>> v;

    // Test data
    const char* data[] = {
        "hello",
        "world",
        "hi",
        nullptr
    };

    // Index in data array
    int i = 0;

    // Insertion loop
    while (data[i] != nullptr)
    {
        // Create new element on the heap
        auto elem = make_shared<A>(i, data[i]);

        // Find ordered insertion position
        auto it = lower_bound(v.begin(), v.end(), elem,
            [](const shared_ptr<A>& lhs, const shared_ptr<A>& rhs)
            {
                return lhs->Key < rhs->Key;
            }
        );

        // Insert in vector
        v.insert(it, elem);

        // Move to next data
        i++;
    }

    // Show the result
    Print(v);
}

出力は次のとおりです。

[ (key=2, data="hi") (key=1, data="world") (key=0, data="hello")  ]
于 2013-05-06T10:52:41.097 に答える