小于函数解引用指针

Less-than function dereferencing pointers

本文关键字:指针 引用 函数 小于      更新时间:2023-10-16

在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++中是否有一种更"标准"的方式,不需要用户制作模板?

通常可以使用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;
}
  • 输出:2 5 6

因此,如果您有std::unique_ptr<double>std::shared_ptr<double>而不是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;
}
  • 相同的输出

没有现成的解决方案。原始指针解引用比较器可以通过以下显式模板专门化使其仅对原始指针类型可用来略微改进。我希望在使用非指针类型的情况下,编译器会给出稍微好一点的错误消息。

template<class T>
struct PointeeLess;
template<class T>
struct PointeeLess<T const *>
{
    bool operator()( T const * a , T const * b ) const { return *a < *b; }
};

问题中的模板将适用于实现operator*的非原始指针类型

我在STL中寻找相同的东西,但找不到它。最后我自己写了(handles 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;
    }

};