2014-12-08 2 views
3

Я хочу иметь set точек, отсортированных по расстоянию до третьей точки. Возможно ли подобное?Пользовательский компаратор, который зависит от значения extern

Я попробовал это, но это не работает:

struct compStruct { 

    Point point; 

    bool operator()(const Point & a, const Point & b) const { return length(a-point)<length(b-point); } 

}; 

void f(const Point & point) { 
    compStruct cs; 
    cs.point = point; 
    std::set<Point, &cs.operator()> pointSet; 
} 

Я не могу использовать лямбда, потому что я хочу использовать этот набор в качестве аргумента другой функции. Так что это не работает:

void g(std::set<Point, pointComp>) {} 
void f(const Point & point) { 
    auto pointComp = [&](const Point & a, const Point & b){ return length(a-point)<length(b-point); }; 
    std::set<Point, pointComp> s; 
    g(s); 
} 

ответ

2

Ваш первый пример должен работать, если вы меняете, как вы объявляя std::set экземпляр:

std::set<Point, compStruct> pointSet(cs); 

Шаблон Безразлично 't ограничивать использование типа функции; вы можете указать класс для использования в качестве компаратора.

Редактировать - обновил пример, чтобы правильно передать экземпляр компаратора.

+1

Но тогда точка не была бы установлена. – gartenriese

+0

Вы правы; вам нужно будет передать экземпляр компаратора, который уже имеет точку, установленную в конструкторе set. – sdzivanovich

+0

Хорошо, это тоже работает. Благодаря! – gartenriese

1

Использование std::function:

#include <functional> 

using Cmp = std::function<bool(const Point & a, const Point & b)>; 

void g(std::set<Point, Cmp>) {} 

void f(const Point & point) 
{ 
    auto pointComp = [&](const Point & a, const Point & b){ return length(a-point)<length(b-point); }; 
    std::set<Point, Cmp> s(pointComp); 
    g(s); 
} 
+0

Это отлично работает, спасибо! – gartenriese

+0

Я бы никогда не догадался использовать разные функции при создании набора. – gartenriese

+0

@gartenriese вы можете свободно настраивать компараторы, используемые в контейнерах, но для контейнера нужен аргумент типа шаблона, указывающий тип компаратора, вы пытались передать сам компаратор (а не его тип) в качестве аргумента типа шаблона, что невозможно. std :: function - это стирание типа, которое может обертывать лямбда-выражения, а также другие вызываемые функции –

Смежные вопросы