![](/img/trans.png)
[英]Sorting only using the less-than operator compared to a trivalue compare function
[英]Less-than function dereferencing pointers
在某些情况下,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::bind1st
和std::bind2nd
简单的std::bind
)。
#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;
}
因此,如果你有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; }
};
OTOH,问题中的模板适用于实现 operator* 的非原始指针类型。
我在 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;
}
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.