Проблема передачи функтора компаратора C ++ в качестве параметра - PullRequest
0 голосов
/ 22 июля 2011

Предположим, у меня есть шаблонный класс LinkedList, который также содержит метод Sort Я хочу иметь возможность иметь компаратор по умолчанию, который предполагает, что тип T можно сравнить с оператором <. </p>

Однако я хочу иметь возможность переопределить это для других типов.

Это часть пользовательской библиотеки, которую я расширяю. Нет STL.

, например

template <class T, class Comparator<T> >
class LinkedList
{
  ...
  Node* MergeSort(Node* list)
  {
      ...
      if (Comparator<T>(nodeA,nodeB))
      ...
  }
  ...
};


typedef Pair<int, int> ListEntry;

struct sorter
{
    inline sorter(){}
    inline bool operator()(ListEntry const& a, ListEntry const& b)
    {
        return a.second < b.second;
    }
};

Pair<int, int> entry;
LinkedList<ListEntry, sorter()> list;

list.PushFront( ListEntry(5,9) );
list.PushFront( ListEntry(77,5) );
list.PushFront( ListEntry(4,1) );
list.PushFront( ListEntry(8,44) );
list.PushFront( ListEntry(1,64) );
list.PushFront( ListEntry(3,5) );
n = list.MergeSort(node* n);

Примерно так выглядит мой класс. На самом деле MergeSort является частным участником данных, но я временно обнародовал его, пока я дурачусь и пытаюсь заставить его работать. MergeSort будет в конечном итоге вызван Sort.

Я не смог скомпилировать это. Просто интересно, как бы вы обычно передавали объекты Functor таким образом.

Ответы [ 2 ]

2 голосов
/ 22 июля 2011

Нельзя сказать template <class T, class Comparator<T>>, т. Е. Иметь один параметр шаблона, который сам является параметром другого параметра.Делайте это так, как это делает стандартная библиотека, и используйте параметры по умолчанию:

template <class T, class Comparator = std::less<T>>
class MyClass
{
  ...
}

Кроме того, Comparator будет объектом, который необходимо создать в какой-то момент.Опять же, аргументы по умолчанию являются ключом:

void MyClass::doSomething(Foo x, Comparator comp = Comparator())
{
  /* ... */
  if (comp(a, b)) { /* ... */ }
  /* ... */
}
1 голос
/ 22 июля 2011

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

template<typename T>
struct LinkedList {
    template<typename Functor>
    Node*
    MergeSort(Node* node, Functor f) {
        // ...
        if(f(NodeA, NodeB)) {
            // ...
        }
        // ...
     }
};
...