Java TreeMap.floorKey() equivalent for std::map I wanted something equivalent to this Java program: 


TreeMap&lt;Integer,Integer&gt; map = new TreeMap&lt;Integer,Integer&gt;();
    map.put(10, 100);
    map.put(20, 200);
    map.put(30, 300);
    map.put(40, 400);
    map.put(50, 500);
    map.put(60, 600);
    map.put(70, 700);
    map.put(80, 800);

    System.out.println(map.floorKey(5));
    System.out.println(map.floorKey(9));
    System.out.println(map.floorKey(10));
    System.out.println(map.floorKey(11));
    System.out.println(map.floorKey(90));



output:


null null 10 10 80



As there is no direct API to achieve the same in C++, I wrote the following code to implement a similar floorKey() function:

template &lt;typename key,typename value&gt;
int floorKey(map&lt;key, value&gt; input, int key)
{
    auto begin = input.begin();
    if (begin-&gt;first &gt; key)//if key is less than the first key. It must retrun -1;
        return -1;

    auto end = input.end();
    end--;
    if (end-&gt;first &lt; key)//if key is greater than last key, it must return last key
        return end-&gt;first;

    //if key is equal to any existing key, it should return the key
    auto find = input.find(key);

    if (find != input.end())
        return key;

    //Return the floor key for the given key
    auto lower = input.lower_bound(key);

    lower--;
    return lower-&gt;first;
}


Here's the test program:

int main()
{
    map&lt;int, int&gt; map;
    map.insert({ 10, 100 });
    map.insert({ 20, 200 });
    map.insert({ 30, 300 });
    map.insert({ 40, 400 });
    map.insert({ 50, 500 });
    map.insert({ 60, 600 });
    map.insert({ 70, 700 });
    map.insert({ 80, 800 });


    cout &lt;&lt; floorKey(map, 5) &lt;&lt; endl;
    cout &lt;&lt; floorKey(map, 9) &lt;&lt; endl;
    cout &lt;&lt; floorKey(map, 10) &lt;&lt; endl;
    cout &lt;&lt; floorKey(map, 11) &lt;&lt; endl;
    cout &lt;&lt; floorKey(map, 90) &lt;&lt; endl;
    return 0;
}


output:


-1 -1 10 10 80



Is there any better way to get the same?  Anything else I can improve?
Headers and namespaces
The function is missing a definition of map.  This is probably what you want:
#include &lt;map&gt;

using std::map;

Similarly, the main() needs:
#include &lt;iostream&gt;
using std::cout;
using std::endl;

That said, there's no good reason for std::endl in this code: an ordinary newline is sufficient, and we don't need the extra flushing behaviour of std::endl.
Naming
It's an error to use the typename key as the name of a parameter here:

template &lt;typename key,typename value&gt;
int floorKey(map&lt;key, value&gt; input, int key)


It's pretty idiomatic to use PascalCase for template arguments, to distinguish them from function parameters:
template&lt;typename Key, typename Value&gt;
int floorKey(std::map&lt;Key, Value&gt; input, Key key)

(I've also corrected the function to accept the correct type for the key argument).
There's a similar problem in main(), where we have a conflict between the type map and our identifier map.  This is one of the reasons I'd argue against bringing the type name into the global namespace.
Don't pass containers by value
We have a potentially large map, which we don't need to modify.  That suggests that it's better passed as a reference to a const object.  As we don't know the type of the key, we should probably assume that it's also better passed by reference (it could plausibly be a std::string, for example).  That gives us:
template&lt;typename Key, typename Value&gt;
int floorKey(const std::map&lt;Key, Value&gt;&amp; input, const Key&amp; key)

It's good that we used auto for the iterators begin and end, as it means that we don't need to change the body of the function to deal with them both now being const iterators.
Think about edge cases
What happens in this code when the input argument is an empty map?  We dereference input.first() without checking whether it's equal to input.end(), giving Undefined Behaviour at that point.
Algorithm
There's really no need to search for an exactly matching key if we then go on to call lower_bound() - we could just call upper_bound() instead, which will find the first key that's strictly greater than key, then decrement (if doing so is valid) to get the result:
auto it = input.upper_bound(key);

return it == input.begin()
    ? -1
    : (--it)-&gt;first;

Note that we have a problem here: if Key isn't a signed numeric type, then we can't return -1.  We really need a type-dependent value for this.  Better still, return a std::optional, so a defaulted value can be clearly distinguished from an actual result.

Modified code
#include &lt;map&gt;
#include &lt;optional&gt;

template&lt;typename Key, typename Value&gt;
std::optional&lt;Key&gt; floorKey(const std::map&lt;Key,Value&gt;&amp; input,
                            const Key&amp; key)
{
    if (auto it = input.upper_bound(key);  it != input.begin()) {
        return (--it)-&gt;first;
    } else {
        return std::nullopt;
    }
}


#include &lt;iostream&gt;

int main()
{
    std::map&lt;int, int&gt; map =
        {
         { 10, 100 },
         { 20, 200 },
         { 30, 300 },
         { 40, 400 },
         { 50, 500 },
         { 60, 600 },
         { 70, 700 },
         { 80, 800 },
        };


    std::cout &lt;&lt; floorKey(map, 5).value_or(-1) &lt;&lt; '\n'
              &lt;&lt; floorKey(map, 9).value_or(-1) &lt;&lt; '\n'
              &lt;&lt; floorKey(map, 10).value_or(-1) &lt;&lt; '\n'
              &lt;&lt; floorKey(map, 11).value_or(-1) &lt;&lt; '\n'
              &lt;&lt; floorKey(map, 90).value_or(-1) &lt;&lt; '\n';
}