Reputation: 25366
I am trying to find the element with the minimum value in the map. For example, if my map has
{ (1, 12.3),(2, 6.51), (3, 1.24)}
I would like to find the element (3, 1.24)
.
I wrote the following code, which tries to write a comparator in the lambda format
std::pair<int, double> min = *std::min_element(
my_map.begin(), my_map.end(),
[](std::unordered_map<int, double> a, std::unordered_map<int, double> b) { return a.second < b.second; });
But I got the following errors:
error: no matching function for call to object of type '(lambda at my_code.cpp:118:9)'
if (__comp(*__i, *__first))
^~~~~~
my_code.cpp:116:40: note: in instantiation of function template specialization 'std::__1::min_element<std::__1::__hash_map_iterator<std::__1::__hash_iterator<std::__1::__hash_node<std::__1::__hash_value_type<int, double>, void *> *> >, (lambda at my_code.cpp:118:9)>' requested here
std::pair<int, double> min = *std::min_element(
^
my_code.cpp:118:9: note: candidate function not viable: no known conversion from 'std::__1::__hash_map_iterator<std::__1::__hash_iterator<std::__1::__hash_node<std::__1::__hash_value_type<int, double>, void *> *> >::value_type' (aka 'pair<const int, double>') to 'std::unordered_map<int, double>' for 1st argument
[](std::unordered_map<int, double> a, std::unordered_map<int, double> b) { return a.second < b.second; });
^
my_code.cpp:118:9: note: conversion candidate of type 'void (*)(std::unordered_map<int, double>, std::unordered_map<int, double>)'
3 errors generated.
Any idea what I did wrong and what's the proper way to fix this? Thanks!
Upvotes: 2
Views: 7713
Reputation: 44258
You are trying to use lambda that accepts maps themselves, not elements of it:
[](std::unordered_map<int, double> a, std::unordered_map<int, double> b)
so it's either (verbose):
[](std::unordered_map<int, double>::value_type a, std::unordered_map<int, double>::value_type b)
or simpler:
[](std::pair<int, double> a, std::pair<int, double> b)
or if you have c++14 or later:
[](auto a, auto b)
you may also consider to pass elements by const reference not to copy them for every iteration.
Upvotes: 6
Reputation: 32847
Your lambda should be binary predicate which takes two pairs of std::pair<const int, double>
.
Change the lambda to as follows:
std::pair<int, double> min = *std::min_element(
my_map.begin(), my_map.end(),
[](const auto &a, const auto &b) { return a.second < b.second; });
or more explicitly:
std::pair<int, double> min = *std::min_element(
my_map.begin(), my_map.end(),
[](const std::pair<const int, double> &a, const std::pair<const int, double> &b) { return a.second < b.second; });
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Upvotes: 6