Почему этот образец работает? - PullRequest
0 голосов
/ 23 апреля 2009
  typedef pair<double, double> dd; 

  const double epsilon = 1e-6;

  struct sort_by_polar_angle { 
    dd center; 
    // Constuctor of any type 
    // Just find and store the center 
    template<typename T> sort_by_polar_angle(T b, T e) { 
        int count = 0;
        center = dd(0,0); 
        while(b != e) { 
                    center.first += b->first;
                    center.second += b->second;
               b++; 
            count++;
        } 
               double k = count ? (1.0/count) : 0;
        center.first *= k;
               center.second *= k;
   } 
   // Compare two points, return true if the first one is earlier 
   // than the second one looking by polar angle 
   // Remember, that when writing comparator, you should 
   // override not ‘operator <’ but ‘operator ()’ 
   bool operator () (const dd& a, const dd& b) const { 
        double p1 = atan2(a.second-center.second, a.first-center.first); 
        double p2 = atan2(b.second-center.second, b.first-center.first); 
        return p1 + epsilon < p2; 
   } 
  }; 

// ... 

vector < dd >  points; 

sort(all(points), sort_by_polar_angle(all(points))); 

Когда вызывается sort_by_polar_angle (), это функция как construnctor? Как правильно использовался перегруженный оператор ()?

Ответы [ 3 ]

4 голосов
/ 23 апреля 2009

Когда вы вызываете sort_by_polar_angle() в функции sort(), вы создаете временный объект типа sort_by_polar_angle (то есть вызывается его конструктор). Внутри алгоритма сортировки переданный вами объект функтора использует что-то вроде functor(), которое будет переведено в functor.operator().

0 голосов
/ 24 апреля 2009

Попробуйте здесь для базового знакомства с функторами или google для c ++ функторов .

0 голосов
/ 23 апреля 2009

Не будет работать для точек на прямой линии от центра. Угол их равен, поэтому их порядок не определен. Сортировка этих точек даст неопределенные результаты.

Это потому, что любая операция «сортировки» должна быть «строгой»: если a a. (на самом деле определение несколько сложнее.)

dd a0 = { 0, 1 };
dd b0 = { 0, 2 };

assert( sort_by_polar_angle ()( a0, b0 ) && ! sort_by_polar_angle () ( b0, a0 ) );
...