Home > front end >  could not convert from ‘<brace-enclosed initializer list>’ to map
could not convert from ‘<brace-enclosed initializer list>’ to map

Time:08-09

my code is as bellow:

class A{
private:
    size_t linearProbing(T k, size_t i);

    size_t quadraticProbing(T k, size_t i);

    size_t doubleHashing(T k, size_t i);

    std::map<std::string, size_t (*)(T, size_t)> probeFunctionMap = {
            {"linearProbing",    this->linearProbing},
            {"quadraticProbing", this->quadraticProbing},
            {"doubleHashing",    this->doubleHashing}
    };
}

And the error is:

error: could not convert '{{"linearProbing", ((HashTableOpeningAddress<int>*)this)->HashTableOpeningAddress<int>::linearProbing}, {"quadraticProbing", ((HashTableOpeningAddress<int>*)this)->HashTableOpeningAddress<int>::quadraticProbing}, {"doubleHashing", ((HashTableOpeningAddress<int>*)this)->HashTableOpeningAddress<int>::doubleHashing}}' from '<brace-enclosed initializer list>' to 'std::map<std::__cxx11::basic_string<char>, long unsigned int (*)(int, long unsigned int), std::less<std::__cxx11::basic_string<char> >, std::allocator<std::pair<const std::__cxx11::basic_string<char>, long unsigned int (*)(int, long unsigned int)> > >'

I guess the method I used to init the map is wrong, but I don't know how to correct it.

CodePudding user response:

A function pointer cannot store the state that you care about (aka this). You need to be able to store this state so that you can call using this later when you use this map. An example might be:

std::map<std::string, std::function<size_t(T, size_t)>>

The std::function will let you store the state. But you cannot create a std::function with this->function_name. That is close to calling the function. So you have 2 options:

  • std::bind - hard
  • lambda - easy

So lets look at a lambda. An example would be:

[this](T k, size_t i) { return functor(k, i); }
  ^ Capture our state, aka `this`
           ^ take the same arguments as the function we care about
                                 ^ Call the function we care about

We can set up a bunch of these lambdas (using a macro for ease):

 #define AS_FUNCTOR(functor) [this](T k, size_t i) { return functor(k, i); }

    std::map<std::string, std::function<size_t(T, size_t)>> probeFunctionMap = {
            {"linearProbing",    AS_FUNCTOR(linearProbing)},
            {"quadraticProbing", AS_FUNCTOR(quadraticProbing)},
            {"doubleHashing",    AS_FUNCTOR(doubleHashing)}

This will make a map that we can use! Live example.

CodePudding user response:

You are mixing C-style and C member function pointers. You have to explicitly qualify A:: everything.

    typedef size_t (A::*ProbeFn)(T, size_t);

    size_t linearProbing(T k, size_t i);
    size_t quadraticProbing(T k, size_t i);
    size_t doubleHashing(T k, size_t i);

    std::map<std::string, ProbeFn> probeFunctionMap = {
            {"linearProbing",    &A::linearProbing},
            {"quadraticProbing", &A::quadraticProbing},
            {"doubleHashing",    &A::doubleHashing}
    };

Then to call:

    size_t useit( const std::string& fname, T t, size_t value ) {
        ProbeFn fn = probeFunctionMap[fname];
        return (*this.*fn)(t,value);
    }

or

 return (this->*fn)(t,value);
  • Related