template <class It>
It min_element_distance(It begin, It end){
using T = iterator_traits<It>::value_type;
auto positive_count = 0;
for_each(begin, end, [&positive_count](T& value){ if (value >= 0) positive_count++; });
auto pos = end;
if (positive_count)
pos = min_element(begin, end, [](T a, T b){ return a >= 0.f && (b < 0.f || a < b); });
if (positive_count == 0 || pos == end)
pos = min_element(begin, end, [](T a, T b){ return abs(a) < abs(b); });
return pos;
}
template <class It ,class GetValue>
It min_element_distance(It begin, It end, GetValue func){
using T = decltype(func(*begin));
auto len = std::distance(begin, end);
vector<T> arr;
arr.reserve(len);
for (auto item = begin; item != end; item++)
arr.push_back(func(*item));
auto pos = min_element_distance(arr.begin(), arr.end());
return begin + distance(arr.begin(),pos);
}
int main(){
vector<pair<float, int>> arr = { make_pair(-40, 0), make_pair(-10, 0), make_pair(-20, 0), make_pair(-30,0) };
cout << min_element_distance(arr.begin(), arr.end(), [](const pair<float, int>& value){return value.first; })->first;
return 0;
}