Navid Mahmoudian
Navid Mahmoudian

Reputation: 27

functions with different names but same arguments

I have a set of functions with the same number of arguments, but different names (suppose each implement different method). I have the name of the requested method in a string. Is it possible to call the corresponding function using the method name. to make it clear, suppose that I have the following function (I just mentioned their name and argument):

search_esa(int a, int b);
search_tss(int a, int b);
search_fss(int a, int b);
search_ds(int a, int b);

now lets assume I have the name of the requested method, lets assume esa, in a string:

string methodName = "esa"

is it possible to call the corresponding function by using macros? I tested

#define CALL_SEARCH_MV(method) search_##method

and then try to call it by:

CALL_SEARCH_MV(methodName.c_str())

but it calls search_methodName function, which does not exist. Any other suggestions would be greatly appreciated (except suggesting switch case method or if).

Upvotes: 0

Views: 478

Answers (4)

ZeroUltimax
ZeroUltimax

Reputation: 256

You can use a combination of Macros, function pointers and clever hacking to achieve the desired result with ease.

In your main.cpp (or where the search functionality lives):

#include <map>
#include <string>
#include <iostream>

typedef int(*search)(int a, int b);

#define SEARCH(x) int search_##x(int a, int b);
#include "search_func.incl"
#undef SEARCH

#define SEARCH(x) {#x, search_##x},
std::map<std::string, search> search_funcs = {
#include "search_func.incl"    
};
#undef SEARCH


int main(char** argv, int argc)
{
    std::cout << search_funcs["esa"](1, 2) << std::endl;
    std::cout << search_funcs["tss"](3, 4) << std::endl;
    std::cout << search_funcs["fss"](5, 6) << std::endl;
    std::cout << search_funcs["ds"](7, 8) << std::endl;

    return 0;
}

int search_esa(int a, int b) { return 100 * a + 10 * b + 0; }
int search_tss(int a, int b) { return 100 * a + 10 * b + 1; }
int search_fss(int a, int b) { return 100 * a + 10 * b + 2; }
int search_ds(int a, int b) { return 100 * a + 10 * b + 3; }

In search_func.incl

SEARCH(esa)
SEARCH(tss)
SEARCH(fss)
SEARCH(ds)

How this works The search_func.incl file specifies the name of your search functions with a macro. When you include the file, you switch up the definition of the macro so that the included functions are presented differently.

SEARCH(abc) 

becomes a function declaration on the first include:

int search_abc(int a, int b);

and a key value pair {string, function pointer} on the second include:

{"abc", search_abc},

These KVP are in a map, so when you need to call a function, the string maps to the function name automatically.

Upvotes: 0

luk32
luk32

Reputation: 16090

You can store function pointers in containers. So you can map pretty much anything. The syntax is pretty simple:

#include <iostream>
#include <map>
using namespace std;

int f1(int a, int b) { return a+b; }
int f2(int a, int b) { return a*b; }

int main() {
    int x = 5;
    int y = 3;
    map<string, int(*)(int, int)> f;

    f["add"] = &f1;
    f["mul"] = &f2;

    cout << f["add"](x,y) << "\n";
    cout << f["mul"](x,y) << "\n";
    return 0;
}

Live: http://ideone.com/wLjw1i.

So you can store any function with matching signature (+return type). This is a the expense of one indirection. The means they are harder to be optimized, because the jump target is set in the run time.

You can make it a bit more general using std::function, again at slight performance expense.

Upvotes: 1

Xirema
Xirema

Reputation: 20396

Something like this would probably work:

std::map<std::string, std::function<void(int, int)>> functions{
    {"esa", search_esa},
    {"tss", search_tss},
    {"fss", search_fss},
    {"ds", search_ds}
};

int main(int argc, char ** argv) {
    std::string cmd = argv[1];
    functions.at(cmd)(5, 10);
    return 0;
}

It's worth noting, though, that you can't really generalize this. If you added another function, like say, search_rsa, you'd have to manually add an entry for it to the map. C++ doesn't have the comprehensive reflection capabilities that a language like Java or Python has, so you can't just write a function that takes a string and searches for a method that has a name matching that string.

Upvotes: 4

Meerkalandar
Meerkalandar

Reputation: 1

Not Possible! the methods defined must be call with the same name. we cannot manipulate the method name.

Upvotes: -1

Related Questions