How do you create an array of member function pointers with arguments?

192 Views Asked by At

I am trying to create a jump table for a fuzzy controller. Basically, I have a lot of functions that take in a string and return a float, and I want to be able to do something along the lines:

float Defuzzify(std::string varName, DefuzzificationMethod defuzz)
{
   return functions[defuzz](varName);
}

where DefuzzificationMethod is an enum. The objective is to avoid a switch statement and have a O(1) operation.

What I have right now is:

float CenterOfGravity(std::string varName);

std::vector<std::function<float (std::string)>> defuzzifiers;

Then I try to initialize it in the constructor with:

defuzzifiers.reserve(NUMBER_OF_DEFUZZIFICATION_METHODS);
defuzzifiers[DEFUZZ_COG] = std::bind(&CenterOfGravity, std::placeholders::_1);

This is making the compiler throw about 100 errors about enable_if (which I don't use anywhere, so I assume std does). Is there a way to make this compile ? Moreover, is there a way to make this a static vector, since every fuzzy controller will essentially have the same vector ?

Thanks in advance

1

There are 1 best solutions below

3
On

Reserve just makes sure there's enough capacity, it doesn't actually mak the vector's size big enough. What you want to do is:

// construct a vector of the correct size
std::vector<std::function<float (std::string)>> defuzzifiers(NUMBER_OF_DEFUZZIFICATION_METHODS);

// now assign into it... 
// if CentorOfGravity is a free function, just simple = works
defuzzifiers[DEFUZZ_COG] = CenterOfGravity; 

// if it's a method
defuzzifiers[DEFUZZ_COG] = std::bind(&ThisType::CenterOfGravity, this, std::placeholders::_1);

Now this might leave you some holes which don't actually have a function defined, so maybe you want to provide a default function of sorts, which the vector constructor allows too

std::vector<std::function<float (std::string)>> defuzzifiers(
    NUMBER_OF_DEFUZZIFICATION_METHODS,
    [](std::string x) { return 0f; }
);

An unrelated note, you probably want your functions to take strings by const-ref and not by value, as copying strings is expensive.