我正在研究数据结构,我希望它具有比较功能,可以传递给构造函数,与stl数据结构(set,queue等)的工作方式相同。我还想要一个构造函数中提供的默认函数。
问题是,对结构的查询是一个函数模板,它将自定义类型作为参数。但如果我不知道查询的类型,我也不知道如何提供默认的比较功能。有没有办法做到这一点?
如果Query与NodeType相同(在此示例中查询无用),则此方法有效:
template<class NodeType, class Query = NodeType>
inline float eucDistance(const Query * p1, const NodeType * p2) {
...
}
template<class NodeType, typename Comp = decltype(eucDistance<NodeType>)>
class KDTree {
Comp* distance;
public:
KDTree(Comp comaprator = &eucDistance<NodeType>) : distance(comaprator) {
}
template<class Query = NodeType>
NodeType * nearestNeighbor(const Query *query) {
...
float tmp = distance(query, sth);
//I want something like distance<NodeType, Query>(query, sth);
...
}
}
但我想做这样的事情:
class Point; //some type that the tree contains
KDTree<Point> tree;
Point p1;
Point *p = tree.nearestNeighbor(&p1); //this works with the given example
...
vec3 vec = ...; //some different type as a query
p = tree.nearestNeighbor<vec3>(vec); // <-- this is what I would like to do
答案 0 :(得分:1)
template<typename Query, typename NodeType = Query>
inline float eucDistance(const Query * p1, const NodeType * p2) {
...
}
class KDTree {
public:
template<typename Query = NodeType, typename Comparator>
NodeType * nearestNeighbor(const Query *query, Comparator comp) {
...
float tmp = comp(query, sth);
...
}
}
此代码接收成员函数级别的比较器,因此它可以采用不同类型的节点。模板类型扣除也会起作用;所以不要像comp<T>(a, b);
那样调用函数,而只需comp(a, b)
就可以了。
你的代码和C ++标准库函数(算法)之间的主要区别在于它们不会强制它们成为指针,而是强制指向函数的C风格指针。相反,他们使用functors。
取std::for_each
调用传递的元素的仿函数;因此需要一个仿函数
template <typename InputIter, typename UnaryFunc>
UnaryFunc std::for_each(InputIter first, InputIter last, UnaryFunc func)
{
for (; first != last; ++first)
func(*first);
return func;
}
如果你注意到,那就没有指针了。它使用运算符func
调用()
;它的优点在于它既适用于C风格的函数指针,也适用于C ++风格的仿函数,即定义了struct
的{{1}}。另请注意,用于函子的模板类型与函子接受的类型无关。
答案 1 :(得分:0)
您应该使用多态仿函数而不是普通函数,例如
struct eucDistance
{
float operator()(Point, Point) const;
float operator()(vec3, Point) const;
...
};
顺便说一下,你真的应该看一下Boost.Geometry并设计R-tree。