C++;关于比较器的模板问题 可能是一个非常新的C++问题。假设我有一个类,vertex,有几个属性和方法。我想把一堆顶点塞进一个队列,并让它们按照vertex类上的一个特殊属性排序(为school yes做一个基本的Dijkstra图算法) 但是我在C++语法中遇到了一些问题。这是我的代码(没有显示vertex,但它非常简单) typedef std::priority_queue q_type; q_类型*q=新的q_类型(); benchmark::vertex*v1=新的benchmark::vertex(0.1,0.1); v1->成本=4; benchmark::vertex*v2=新的benchmark::vertex(0.1,0.1); v2->成本=8; benchmark::vertex*v3=新的benchmark::vertex(0.1,0.1); v3->成本=6; benchmark::vertex*v4=新的benchmark::vertex(0.1,0.1); v4->成本=10; benchmark::vertex*v5=新的benchmark::vertex(0.1,0.1); v5->成本=2; q->push(v1); q->push(v2); q->push(v3); q->push(v4); q->push(v5); 而(!q->empty()){ std::cout top()).cost pop(); }
这将在本地机器上输出2、10、6、8、4。我正在使用GCC(GCC版本4.3.3(ubuntu4.3.3-5ubuntu4))在Linux上测试这一点。显然,我想让它把数字按顺序排出来 在进行比较时,如何制作比较器,使其看起来并比较vertex.cost?使用任何函数或函子替换C++;关于比较器的模板问题 可能是一个非常新的C++问题。假设我有一个类,vertex,有几个属性和方法。我想把一堆顶点塞进一个队列,并让它们按照vertex类上的一个特殊属性排序(为school yes做一个基本的Dijkstra图算法) 但是我在C++语法中遇到了一些问题。这是我的代码(没有显示vertex,但它非常简单) typedef std::priority_queue q_type; q_类型*q=新的q_类型(); benchmark::vertex*v1=新的benchmark::vertex(0.1,0.1); v1->成本=4; benchmark::vertex*v2=新的benchmark::vertex(0.1,0.1); v2->成本=8; benchmark::vertex*v3=新的benchmark::vertex(0.1,0.1); v3->成本=6; benchmark::vertex*v4=新的benchmark::vertex(0.1,0.1); v4->成本=10; benchmark::vertex*v5=新的benchmark::vertex(0.1,0.1); v5->成本=2; q->push(v1); q->push(v2); q->push(v3); q->push(v4); q->push(v5); 而(!q->empty()){ std::cout top()).cost pop(); },c++,templates,graph,C++,Templates,Graph,这将在本地机器上输出2、10、6、8、4。我正在使用GCC(GCC版本4.3.3(ubuntu4.3.3-5ubuntu4))在Linux上测试这一点。显然,我想让它把数字按顺序排出来 在进行比较时,如何制作比较器,使其看起来并比较vertex.cost?使用任何函数或函子替换std::less,该函数或函子将两个顶点指针作为参数,并在第一个参数位于第二个参数之前时返回true std::less将比较这两个指针,因此您看到的结果将显示它们在内存中的顺序。std::less比较的是地址而不是顶点
std::less
,该函数或函子将两个顶点指针作为参数,并在第一个参数位于第二个参数之前时返回true
std::less
将比较这两个指针,因此您看到的结果将显示它们在内存中的顺序。std::less
比较的是地址而不是顶点
// Functor
struct VertexLess
{
bool operator (const benchmark::vertex* left, const benchmark::vertex* right) const {
return left->id < right->id;
}
};
typedef std::priority_queue<benchmark::vertex*,
std::vector<benchmark::vertex*>,
VertexLess > q_type;
//函子
无顶点结构
{
布尔运算符(常数基准::顶点*左,常数基准::顶点*右)常数{
返回左->id<右->id;
}
};
typedef std::优先级队列q_类型;
亚历克赛·马利斯托夫答案的额外模板版:
template <class T, class M, const M T::*member>
struct MemberGenericDereferenceLess
{
bool operator()(const T* lhs, const T* rhs) const
{
return ((*lhs).*member < (*rhs).*member);
}
};
typedef std::priority_queue<benchmark::vertex*,
std::vector<benchmark::vertex*>,
MemberGenericDereferenceLess<benchmark::vertex,
int,
&benchmark::vertex::cost> > q_type;
您可以在a
或b
上进行typedef排序:
typedef std::priority_queue<benchmark::vertex*,
std::vector<benchmark::vertex*>,
MemberGenericDereferenceLess<benchmark::vertex,
double,
&benchmark::vertex::a> > q_type;
typedef std::priority_queue<benchmark::vertex*,
std::vector<benchmark::vertex*>,
MemberGenericDereferenceLess<benchmark::vertex,
double,
&benchmark::vertex::b> > q_type;
typedef std::priority_queue q_type;
typedef std::优先级队列q_类型;
下面是一个小的驱动程序:
#include <iostream>
#include <queue>
#include <vector>
namespace benchmark
{
struct vertex
{
vertex(double a_, double b_) : a(a_), b(b_) {}
double a;
double b;
int cost;
};
}
template <class T, class M, const M T::*member>
struct MemberGenericDereferenceLess
{
bool operator()(const T* lhs, const T* rhs) const
{
return ((*lhs).*member < (*rhs).*member);
}
};
int main(int argc, char** argv)
{
typedef std::priority_queue<benchmark::vertex*,
std::vector<benchmark::vertex*>,
MemberGenericDereferenceLess<benchmark::vertex,
int,
&benchmark::vertex::cost> > q_type;
q_type q;
benchmark::vertex* v1 = new benchmark::vertex(0.1,0.1);
v1->cost = 4;
benchmark::vertex* v2 = new benchmark::vertex(0.1,0.1);
v2->cost = 8;
benchmark::vertex* v3 = new benchmark::vertex(0.1,0.1);
v3->cost = 6;
benchmark::vertex* v4 = new benchmark::vertex(0.1,0.1);
v4->cost = 10;
benchmark::vertex* v5 = new benchmark::vertex(0.1,0.1);
v5->cost = 2;
q.push(v1);
q.push(v2);
q.push(v3);
q.push(v4);
q.push(v5);
while(q.empty() == false)
{
std::cout << q.top()->cost << std::endl;
q.pop();
}
// Clean up all of those new()s
delete v1;
delete v2;
delete v3;
delete v4;
delete v5;
std::cin.get();
return 0;
}
#包括
#包括
#包括
名称空间基准
{
结构顶点
{
顶点(双a_,双b_):a(a_),b(b_){
双a;
双b;
国际成本;
};
}
模板
结构成员泛型无引用
{
布尔运算符()(常数T*lhs,常数T*rhs)常数
{
返回((*lhs)。*成员<(*rhs)。*成员);
}
};
int main(int argc,字符**argv)
{
typedef std::优先级队列q_类型;
q_型q;
benchmark::vertex*v1=新的benchmark::vertex(0.1,0.1);
v1->成本=4;
benchmark::vertex*v2=新的benchmark::vertex(0.1,0.1);
v2->成本=8;
benchmark::vertex*v3=新的benchmark::vertex(0.1,0.1);
v3->成本=6;
benchmark::vertex*v4=新的benchmark::vertex(0.1,0.1);
v4->成本=10;
benchmark::vertex*v5=新的benchmark::vertex(0.1,0.1);
v5->成本=2;
q、 推(v1);
q、 推送(v2);
q、 推(v3);
q、 推送(v4);
q、 推送(v5);
while(q.empty()==false)
{
std::cout cost您需要指定“vertext cost”的含义。@Neil,“cost”是顶点类+1bool costFunction(const benchmark::vertex*lhs,benchmark::vertex*rhs){return lhs->costcost;}
@Andreas,您如何在模板声明中包含此函数?纯benchmark::costFunction
不作为第三个参数。尝试将其添加到vertex并使用benchmark::vertex::operator@Svend,关于第三个模板参数,您会遇到什么错误?下面是一个示例。我想我得去读一下Compare类。@Svend,那语法是错误的。Alexey的回答显示了一种正确语法的方法。那太令人印象深刻了!我想!;)谢谢。我对模板允许的灵活性很着迷:)
typedef std::priority_queue<benchmark::vertex*,
std::vector<benchmark::vertex*>,
MemberGenericDereferenceLess<benchmark::vertex,
double,
&benchmark::vertex::a> > q_type;
typedef std::priority_queue<benchmark::vertex*,
std::vector<benchmark::vertex*>,
MemberGenericDereferenceLess<benchmark::vertex,
double,
&benchmark::vertex::b> > q_type;
#include <iostream>
#include <queue>
#include <vector>
namespace benchmark
{
struct vertex
{
vertex(double a_, double b_) : a(a_), b(b_) {}
double a;
double b;
int cost;
};
}
template <class T, class M, const M T::*member>
struct MemberGenericDereferenceLess
{
bool operator()(const T* lhs, const T* rhs) const
{
return ((*lhs).*member < (*rhs).*member);
}
};
int main(int argc, char** argv)
{
typedef std::priority_queue<benchmark::vertex*,
std::vector<benchmark::vertex*>,
MemberGenericDereferenceLess<benchmark::vertex,
int,
&benchmark::vertex::cost> > q_type;
q_type q;
benchmark::vertex* v1 = new benchmark::vertex(0.1,0.1);
v1->cost = 4;
benchmark::vertex* v2 = new benchmark::vertex(0.1,0.1);
v2->cost = 8;
benchmark::vertex* v3 = new benchmark::vertex(0.1,0.1);
v3->cost = 6;
benchmark::vertex* v4 = new benchmark::vertex(0.1,0.1);
v4->cost = 10;
benchmark::vertex* v5 = new benchmark::vertex(0.1,0.1);
v5->cost = 2;
q.push(v1);
q.push(v2);
q.push(v3);
q.push(v4);
q.push(v5);
while(q.empty() == false)
{
std::cout << q.top()->cost << std::endl;
q.pop();
}
// Clean up all of those new()s
delete v1;
delete v2;
delete v3;
delete v4;
delete v5;
std::cin.get();
return 0;
}