2013-08-04 3 views
6

Попытка переопределить map::compare Функция, использующая лямбда, кажется, что работает следующее решение.переопределить карту :: сравнить с функцией лямбда напрямую

auto cmp = [](const int&a, const int& b) { return a < b; }; 
std::map<int, int, decltype(cmp)> myMap(cmp); 

Прежде всего, я должен был определить cmp и использовать его позже.
Могу ли я это сделать без определения «cmp»?

+2

'cmp' не является указателем на функцию. –

+1

Do _what_? 'int' уже сравниваются друг с другом. Что ты пытаешься сделать? И почему вы не хотите использовать функцию? –

+0

Да, указатель функции не был точным термином. Отредактировал вопрос, чтобы сделать вопрос более ясным. – MBZ

ответ

12

Нет, вы не можете использовать лямбда в неоценимом контексте - то есть параметры шаблона, как в вашем примере. Таким образом, вы должны определить его где-то еще (с помощью auto), а затем использовать decltype ... другой путь, как это было сказано уже является использование «порядковые» функторы

Если речь идет о "хау использовать лямбда-выражения * раз * когда определяют отображение "вы можете использовать неявное преобразование лямбды в std::function так:

#include <iostream> 
#include <functional> 
#include <map> 

int main() 
{ 
    auto m = std::map<int, int, std::function<bool(const int&, const int&)>>{ 
     [](const int& a, const int& b) 
     { 
      return a < b; 
     } 
    }; 
    return 0; 
} 

вы можете ввести псевдоним для этого типа map к г educe typing later ...

+0

Однако использование 'std :: function' добавит уровень косвенности и сделает его менее эффективным. – newacct

2

Вы можете сделать что-то подобное, когда тип карты выводится из функции, которую вы передаете функции.

#include <map> 

template<class Key, class Value, class F> 
std::map<Key, Value, F> make_map(const F& f) { 
    return std::map<Key, Value, F>{f}; 
} 

int main() { 
    auto my_map = make_map<int, int>([](const int&a, const int& b) { return a < b; }); 
    my_map[10] = 20; 
} 

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

tempalte<class F> 
void do_somthing(const std::map<int, int, F>& m) { 

} 

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

#include <map> 
#include <functional> 

template<class Key, class Value> 
using my_map_t = std::map<Key, Value, std::function<bool(const Key&, const Key&)>>; 

int main() { 
    my_map_t<int, int> my_map{[](const int&a, const int& b) { return a < b; }}; 
    my_map[10] = 20; 
} 

Теперь вы можете использовать любой предикат вы хотите, и у вас есть конкретный тип для работы, my_map

надеюсь, что это помогает!

6
#include <iostream> 
#include <functional> 
#include <map> 
#include <typeinfo> 

typedef std::map< int, int, std::function<bool(const int&, const int&)> > MyMap; 

int main() 
{ 
    auto cmp = [](const int& a, const int& b) { return a < b; }; 
    MyMap map(cmp); 

    return 0; 
} 

Использование std::function для обеспечения соответствующего типа подписи для типа сравнения вы можете определить свой тип карты, а затем назначить любую лямбду сравнение вы хотите.

+4

Это то, что просит ОП, но на самом деле введение 'std :: function' похоже на плохое решение. Как насчет шаблона псевдонимов? 'template с использованием MyMap = std :: map ;', и вам не нужно определять компаратор, пока вы не создадите экземпляр карты. – Praetorian

+0

@Praetorian Я застрял с неполным компилятором (VS2012), который не поддерживает шаблонные псевдонимы, поэтому у меня нет опыта с ними. – Borgleader

+0

шаблонные псевдонимы никоим образом не помогли: __You не может использовать лямбда в неоценимом контексте__, но вы должны указать параметр 'Comp' в любом случае (в точке создания экземпляра). – zaufi

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