5

STL コンテナー内にポインターがあり、ポインターではなく、ポイントされたオブジェクトによってより小さい比較が行われる場合があります。簡単な例は、実数でソートされるベクトルです。現在、私はこれを次のように解決します:

template<class T_PTR> struct ltDeref
{
    bool operator()(T_PTR p0,T_PTR p1) const {return *p0<*p1;}
};

そしてそれを次のように使用します

vector<double*> vIn;
sort(vIn.begin(),vIn.end(),ltDeref<double*>());

また

set<double*,ltDeref<double*> > someSet;

私自身の比較関数を書く代わりに、ユーザーが作成したテンプレートを必要としない C++ のより「標準的な」方法はありますか?

4

3 に答える 3

1

多くの場合、 で利用可能なファンクターを使用しfunctionalて、純粋に標準的な構造から結果のソート ファンクターを構築できます。

ただし、ポインターを逆参照するものはないT*ため、独自のコンパレーターを使用する必要があります。


最も近いのは、「ポインター型」がプリミティブではなく、operator*アドレス指定できるユーザー定義型の場合です。

次のコードは C++11 です ( と よりも簡単に使用できますstd::bind) 。std::bind1ststd::bind2nd

#include <vector>
#include <algorithm>
#include <functional>
#include <iostream>

// Fakes a "smart pointer" wrapper around data
template <typename T>
struct Ptr
{
    Ptr(T data) : data(data) {};
    const T& operator*() const { return data; }

private:
    T data;
};

int main()
{
    std::vector<Ptr<double>> vIn;
    vIn.push_back(Ptr<double>(5));
    vIn.push_back(Ptr<double>(2));
    vIn.push_back(Ptr<double>(6));

    using namespace std::placeholders;
    std::sort(
        vIn.begin(),
        vIn.end(),
        std::bind(
            std::less<double>(),
            std::bind(&Ptr<double>::operator*, _1),
            std::bind(&Ptr<double>::operator*, _2)
        )
    );

    std::vector<Ptr<double>>::const_iterator it = vIn.begin(), end = vIn.end();
    for ( ; it != end; ++it)
        std::cout << ',' << **it;
}

そのため、代わりにまたはがある場合、これは機能する可能性がありdouble*ます。std::unique_ptr<double>std::shared_ptr<double>

#include <vector>
#include <memory>
#include <algorithm>
#include <functional>
#include <iostream>

int main()
{
    typedef std::unique_ptr<double> STDUPD;

    std::vector<STDUPD> vIn;
    vIn.push_back(STDUPD(new double(5)));
    vIn.push_back(STDUPD(new double(2)));
    vIn.push_back(STDUPD(new double(6)));

    using namespace std::placeholders;
    std::sort(
        vIn.begin(),
        vIn.end(),
        std::bind(
            std::less<double>(),
            std::bind(&STDUPD::operator*, _1),
            std::bind(&STDUPD::operator*, _2)
        )
    );

    std::vector<STDUPD>::const_iterator it = vIn.begin(), end = vIn.end();
    for ( ; it != end; ++it)
        std::cout << ',' << **it;
}

可能であれば、「生の」ポインターを避けるもう1つの理由...

于 2012-12-30T11:33:47.583 に答える
0

STLで同じものを探していましたが、見つかりませんでした。自分で書くことになった(NULLを処理する)

class DeRefPtrLess {

public:

template<typename T>
    bool operator()(const T *l, const T *r) const {
        if (l == NULL
                && r == NULL) {
            return false;
        }
        if (l == NULL) {
            return true;
        }

        return *l < *r;
    }

};

于 2020-09-18T17:26:51.610 に答える