2013-05-02 1 views
1

Я пытаюсь реализовать/использовать интерфейс стиля компаратора, такой как тот, который вы найдете в Java, который позволит мне передать общий тип компаратора функции и использовать ее для сортировки набор данных.C++ Custom Comparison Function с шаблоном как функциональный параметр

Это потому, что мне нужны различные функции сравнения, и я хочу иметь возможность передать тот, который мне нужен, в функцию сортировки.

Вот фрагмент кода, что я до сих пор, и, надеюсь, вы можете сказать, что я имею в виду:

void Population::sort(const std::shared_ptr<Comparator<Solution>>& comparator) 
{ 
    std::sort(data.begin(), data.end(), comparator.get()); 
} 

И интерфейс компаратор я пытался реализовать

template <typename T> class Comparator : public std::binary_function<T,T,bool> 
{ 
public: 
    virtual ~Comparator(); 
    virtual bool operator() (const T &o1, const T &o2 ) = 0; 
}; 

Это, вероятно, что-то Очевидно, я делаю неправильно, так как не знаю много C++.

Cheers!

+0

Я думаю, что вы закончили инженерное дело. виртуальные методы в компараторах, и вы, скорее всего, можете использовать 'std :: reference_wrapper' для экземпляра функторов со стороны вызывающего абонента. – juanchopanza

ответ

2

Если вы явно не нужно менять сравнения предикат во время выполнения Я хотел бы выбрать, чтобы сделать Функция Population :: sort: функция шаблона:

struct Person 
{ 
    std::vector<int> v; 

    template<typename P> 
    void sort(P& p) 
    { 
     std::sort(v.begin(), v.end(), p); 
    } 
}; 

Это дает вам широкий спектр опций для вашего предиката. Такие как:

bool mycompare(int a, int b) 
{ 
    return a < b; 
} 

struct predicate 
{ 
    bool operator()(int a, int b) 
    { 
     return a < b; 
    } 
}; 

struct myclass 
{ 
    bool function(int a, int b) 
    { 
     return a < b; 
     } 
}; 

int main() 
{ 

    Person p; 

    // you can use a lambda 
    p.sort([](int a, int b){return a < b;}); 
    // you can use a functor 
    predicate pred; 
    p.sort(pred); 
    // you can use a free function 
    p.sort(mycompare); 
    // you can bind to a class member function 
    myclass c; 
    p.sort(std::bind(&myclass::function, &c, std::placeholders::_1, std::placeholders::_2)); 
    std::copy(p.v.begin(), p.v.end(), std::ostream_iterator<int>(std::cout)); 
} 

Использование таких функций шаблона, как это позволяет обеспечить большую гибкость.

+0

Perfect! Большое спасибо за вашу помощь, а также за внимание, чтобы детализировать альтернативы. – masterjonny

0

Во-первых: вы должны правильно реализовать свой компаратор. Что-то вроде:

template <typename T> 
struct Comparator : public std::binary_function<T,T,bool> 
{ 
    bool operator()(const T& o1, const T& o2) 
    { 
     return o1 < o2; 
    } 
} 

Во-вторых, вы должны поместить экземпляр вашего компаратора STD :: вид:

std::sort(data.begin(), data.end(), Comparator<Solution>()); 
+0

Но разве это не означает, что я не могу переопределить его, поскольку он больше не является виртуальным? Кроме того, я хочу, чтобы иметь возможность передавать компаратор в качестве параметра в сортировке, и я не думаю, что смогу сделать это таким образом? – masterjonny

+0

Почему вы хотите переопределить его? Вы всегда можете выполнить определенную реализацию своего шаблона. std :: sort принимает Compare (двоичная функция) в качестве третьего параметра, поэтому вы должны создать экземпляр вашего компаратора, чтобы передать его для сортировки функции –