Error inserting a function as value into a std::map

I am trying to create a std::map that has an integer as the key and a function as the value. When I try to insert a value, either via = or insert(), I get the following error:

Error C2207 'std::pair<_Ty1,_Ty2>::second': a member of a class template cannot acquire a function type

Here is the sample code:

std::map<int, std::function<void()>> myMap;
myMap[0] = [] {std::cout << "zero\n"; };
myMap.insert(std::make_pair<int, std::function<void()> >(0, [] {std::cout << "zero\n";} ) ) 

Why can't I do this, and how do I fix it?

Upvotes: 0

Views: 158

Answers (1)

Pepijn Kramer
Pepijn Kramer

Reputation: 13081

A lambda is not a std::function, so you need to do a bit more work. Usually I have a class with a map as member and a function template that allows to add lambda. Here is some code without such a wrapper.

Note that initializing at construction is by far the easiest way to do it. Then the constructor of std::function<void()> is called with the lambda (which is fine).

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

template<typename fn_t>
auto to_fn(fn_t&& fn)
{
    return std::function<void()>{fn};
}


int main()
{
    std::map<int, std::function<void()>> map
    {
        { 0, [] { std::cout << "0\n"; }}
    };

    // map.insert(1, []{ std::cout << "1\n"; }); a lambda is not a function

    map.insert({ 1, std::function<void()>{ [] { std::cout << "1\n"; } } });
    map.insert({ 2, to_fn([] { std::cout << "2\n"; }) });


    map[2]();
    
    return 0;
}

Upvotes: 2

Related Questions