我正在尝试在C#中实现k-d树,而我正在查看的源代码是C ++和Boost。我想找的函数是util::subtract()
。我通过Boost的文档搜索过,我无法在任何地方找到它。
第94行是我试图翻译的功能。 完整文件可在此处找到:https://github.com/gvd/kdtree/blob/master/kdtree.h
如果某人有更好的来源我可以实施,我也非常感谢。
答案 0 :(得分:2)
您正在查看的是C ++内联函数模板,它实际上是在您链接的头文件的顶部定义的(因此util::
命名空间而不是boost::
命名空间)。在C#中,如果将Dimension
字段从包含struct
的C ++中取出并将其作为第四个参数传递给C#静态函数,则看起来可以在静态函数中实现此逻辑。 / p>
subtract(...)
有3种不同的功能模板定义,但只有一种具有实质内容。为了完整性,我将在此处包含该函数模板主体(请注意,它包含一个递归调用,其中Dimension
字段用作计数器,一旦它等于dim
就会限制递归:
template <typename Point, std::size_t Dimension, std::size_t Count>
struct dimension_extractor {
static inline typename boost::geometry::default_distance_result<Point>::type subtract(const Point &p1, const Point &p2, std::size_t dim) {
if (Dimension == dim) {
return boost::geometry::get<Dimension>(p1) - boost::geometry::get<Dimension>(p2);
}
return dimension_extractor<Point, Dimension + 1, Count>::subtract(p1, p2, dim);
}
};
诚然,如果不检查boost::geometry
库,C#的直接粗略端口可能看起来像这样的伪代码:
public static boost.geometry.default_distance_result<Point>.type subtract(Point p1, Point p2, uint dim, uint currDim)
{
if (currDim == dim)
{
// it looks like .get() is a templated function, so the actual call syntax may be somewhat different
return boost.geometry.get(p1, currDim) - boost.geometry.get(p2, currDim);
}
else
return subtract(p1, p2, dim, currDim + 1);
}
在C ++上下文中,似乎currDim
参数(表示Dimension
struct字段)始终在零处初始化并递增,直到达到dim
。我不确定为什么这种明显不必要的递归正在发生 - 它可能只是一个C ++编译器技巧(C ++模板通常比相关的C#泛型更不清晰)。如果是这种情况,您可能只能完全从C#代码中删除递归方面。