#include <iostream>
#include <algorithm>
#include <map>
using namespace std;

template<typename Map, typename K>
auto tolerant_find(const Map & map, const K & lookup, const K & tolerance) -> decltype(map.begin()) {
    // Assuming (first,last) is a sorted sequence of pairs

    // First, find sub-sequence of keys "near" the lookup value
    auto first = map.lower_bound(lookup - tolerance);
    auto last = map.upper_bound(lookup + tolerance);
    
    // If they are equal, the sequence is empty, and thus no entry was found.
    // Return the end iterator to be consistent with std::find.
    if (first == last) {
    	return map.end();
    }

    // Then, find the one with the minimum distance to the actual lookup value
    typedef typename Map::mapped_type T;
    return std::min_element(first, last, [lookup](std::pair<K,T> a, std::pair<K,T> b) {
        return std::abs(a.first - lookup) < std::abs(b.first - lookup);
    });
}

int main() {
	std::map<float,int> mymap = {
		{ 1.0, 1 },
		{ 5.0, 2 },
		{ 5.1, 3 },
		{ 5.11, 4 },
		{ 5.2, 5 }
	};
	
	// This should find the key 5.11
	cout << tolerant_find(mymap, 5.15, 0.1)->first << endl;
	// This should find the key 5.2
	cout << tolerant_find(mymap, 5.16, 0.1)->first << endl;
	
	// This should print "not found".
	cout << (tolerant_find(mymap, 2.0, 0.1) == mymap.end() ? "not found" : "found") << endl;
	
	return 0;
}