我有关于仿函数的问题。我建了一个简单的类:
class PolygonPrinter {
private:
std::vector<float> x;
std::vector<float> y;
public:
inline void operator()(Point& p) {
x.push_back(boost::geometry::get<0>(p));
y.push_back(boost::geometry::get<1>(p));
}
void printPoints() {
for(int i=0; i < x.size(); i++) {
std::cout << "("
<< x[i] << "," << y[i]
<< ")" << std::endl;
}
}
}
我想用它作为一个仿函数。这用于类似的东西
PolygonPrinter<point_2d> polyPrinter;
boost::geometry::for_each_point( polygon, polyPrinter );
polyPrinter.printPoints();
现在看来仿函数部分工作正常,因为我看到向量填充了所有多边形元素(因此for_each_point按预期工作),但是,第三个调用(printPoints)不打印任何点,实际上两个向量都是空的。我想这种行为是可以预料的,然而,我无法理解向量是如何被清除的。我以为你可以有状态的仿函数。
为什么polyPrinter实例中的向量字段x和y为空?
std
算法复制你的算子。 boost
可能会做同样的事情。
你可以std::ref( functor )
通过伪参考传递它,你会得到你想要的行为。
boost::geometry::for_each_point( polygon, std::ref(polyPrinter) );
顺便说一句,你对inline
的使用是多余的:在类的主体中定义的所有方法都是隐含的inline
。这是追踪错误的一些乐趣的来源。
这与PolygonPrinter
的情况不同。
Boost API的定义是:
template<typename Geometry, typename Functor>
Functor for_each_point(Geometry & geometry, Functor f)
仿函数通过副本传递!因此,您实际上为Boost API创建了一个新实例,因此它不会影响您的实例。如果您想捕获新状态(在使用for_each_point
之后),请使用返回值将您的实例重新分配给一个Boost返回。当然,这假设您的复制构造函数符合您的预期:以某种方式复制您需要的值。在您的特定情况下,您具有默认的复制构造函数,因此它应该按预期工作。
PolygonPrinter<point_2d> polyPrinter;
polyPrinter = boost::geometry::for_each_point( polygon, polyPrinter );
polyPrinter.printPoints();