2015-03-19 81 views
1

我有一个关于函数的问题。我建立了一个简单的类:C++有状态函子,填充向量

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是空的,那就太好了。

干杯

+1

我的猜测是,您的for_each_point正在获取原始polyPrinter的副本。因此,副本填充了点,你看到它,但原来仍然是空的 – 2015-03-19 02:48:35

回答

2

std算法复制你的仿函数。 boost可能也是这样。

你可以std::ref(functor)通过伪引用传递它,你会得到你想要的行为。

boost::geometry::for_each_point(polygon, std::ref(polyPrinter)); 

顺便说一句,你的inline使用是多余的:在类的主体定义的所有方法都隐含inline。这是追踪错误的一些乐趣的来源。

+0

谢谢!这工作。 – 2015-03-19 03:55:43

+0

@alvini如果这可以解决您的问题,将其标记为答案的官方方法是给它一个复选标记。左边有一个按钮可以按下。 – Yakk 2015-03-19 10:53:37

+0

对不起。 – 2015-03-20 11:35:26

0

这不是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(); 
+0

我明白了!谢谢。我应该想到这一点。 – 2015-03-19 03:55:21