简体   繁体   中英

c++ std::map compare function leads to runtime "bad_function_call"

I'm declaring my std::map and use it below:

    map<int, int, function<bool (int, int)>> m;
    m.insert(make_pair(12,3));
    m.insert(make_pair(3,4));
    for(auto & p : m){
        cout << p.first << "," << p.second << endl;
    }

g++ compiles, no error. Template parameter only requires a type, but no function body is required, passes compilation. I was wondering how this empty comparer would behave. On running it:

terminate called after throwing an instance of 'std::bad_function_call'
  what():  bad_function_call

I only see this error in calling pure virtual function. But my code is using stl template, no polymorphism is in place.

So is this a c++ design issue, that compilation doesn't check if a function only has declaration but no function body to run? Plus, how would c++ standard deal with this?

Appreciate your explanations.

map<int, int, function<bool (int, int)>> m;

You declared std::map to use your own comparator whose signature is bool(int, int) , but did not supply a callable functor.

You should declare a real callable object and pass it to constructor so that your map can call it when needed.

auto order_by_asc = [](int n1, int n2)->bool {return (n1 < n2); };
std::map<int, int, std::function<bool(int, int)>> m(order_by_asc);

The problem is not related to the template argument, but that you did not provide an actual value for it when constructing the map.

Note that in the documentation for the map constructor, there is a const Compare& parameter. It is via this parameter that you must give a value for your comparator which in this case is a lambda.

explicit map( const Compare& comp,
              const Allocator& alloc = Allocator() );

For example:

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

using namespace std;

int main()
{
    auto comp = [](int a, int b) { return a > b; };
    map<int, int, function<bool (int, int)>> m(comp);
    m.insert(make_pair(12,3));
    m.insert(make_pair(3,4));
    for(auto & p : m){
        cout << p.first << "," << p.second << endl;
    }
}

Outputs:

12,3
3,4

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM