2013-07-13 6 views
1

I ma пишет функцию шаблона, которая принимает вектор элементов и выполняет последовательность некоторых операций над ним. Одной из этих операций является std :: sort().C++/STL Компаратор по умолчанию

Естественно, клиентский код должен поставлять функтор компаратора. Я не хочу, чтобы код клиента указывал значение для этого параметра, если он проходит в контейнере известных типов (ints, string и т. Д.). Как определить значение по умолчанию для параметра моего шаблона Comp?

template<typename Container, typename Comp=????> 
void my_func(Container elements, Comp comp) { 
    ... 
    std::sort(elements.begin(), elements.end(), comp); 
    ... 
} 
+0

Обратите внимание, что 'станд :: sort' не может быть эффективным на' станд :: list'; по этой причине 'std :: list' имеет функцию' .sort'. – dyp

+1

typo в вашем коде, вы написали "typenam Container", это должно быть "typename" – Borgleader

ответ

2

станд :: сортировка использует «Меньше», как по умолчанию компаратор. Таким образом, чтобы сохранить его последователен:

template<typename Container, typename Comp = std::less<typename Container::value_type> > 
void my_func(Container& elements, Comp comp = Comp()) 
{ 
    std::sort(elements.begin(), elements.end(), comp); 
} 
+0

Да, вы правы, спасибо. – AngelCastillo

0
#include <vector> 
#include <algorithm> 

template<typename Container, typename Comp=std::less<typename Container::value_type>> 
void my_func(Container elements, Comp comp = Comp()) { 
    //... 
    std::sort(elements.begin(), elements.end(), comp); 
    //... 
} 

int main() { 
    std::vector<int> v; 
    my_func(v); 
} 

Отметим также Comp comp = Comp()

0

Я бы не по умолчанию сам шаблон, но вместо параметра функции во что-то похожее на std::greater или std::less для > и < соответственно. std::sort использует std::less по умолчанию.

Если вы хотите получить для него параметр шаблона, то есть предложение сделать std::greater<> для работы с обобщенными типами N3421, который был фактически принят для C++ 14.

Однако до этого вы можете сделать std::greater<typename Container::value_type>. Вы можете выбрать удаление ссылочных или cv-квалификаторов с помощью type_traits, если хотите.

<functional> имеет другие сравнения по умолчанию, но эти два являются наиболее распространенными.

Так что «полное» решение было бы что-то вроде этого:

template<typename Container, typename Comp> 
void my_func(Container& elements, Comp comp = std::less<typename Container::value_type>()) { 
    std::sort(elements.begin(), elements.end(), comp); 
} 
0

В вашем примере есть 2 проблемы:

  1. , чтобы сделать поведение по умолчанию, вы должны suplly less<T> как функтор.

  2. Ваша функция принимает копию так, то копия будет отсортирован, если не принимать refence к Container вместо этого.

Пример как сделать это:

#include <functional> 
template<typename Container, typename Comp=std::less<typename Container::value_type> > 
void my_func(Container &elements, Comp comp = Comp()) 
{ 
    std::sort(elements.begin(), elements.end(), comp); 
} 
// A partial specialisation for std::list 
#include <list> 
template<typename ContainerValueType, typename Allocator, typename Comp=std::less<ContainerValueType> > 
void my_func(std::list<ContainerValueType, Allocator> &elements, Comp comp = Comp()) 
{ 
    elements.sort(comp); 
} 
+0

+1 для того, чтобы быть единственным, кто исправит проблему передачи по значению. – AngelCastillo

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