Tez
Tez

Reputation: 527

How to call a function based on the input value?

Lets say I want to only call one function in my code: func(), but depending on which value I give it, have it go STRAIGHT to the correct 'version' of that function?

I know this would be possible to do with if-statements/switch-statements, but then it would have to (inefficiently) check which value was passed. I was hoping there's a pre-compiled way to do it?

Is something like this possible to do in an efficient way?

func(3)

Will execute the third version of func()

func[1]{
    cout "One";
}

func[2]{
    cout "Two";
}

func[3]{
    cout "Three";
}

Upvotes: 1

Views: 3926

Answers (6)

Patashu
Patashu

Reputation: 21773

Actually, case-switch is very efficient, because even if you have a very large number of targets, it can compile this in the code as a table of jumps, rather than as a chain of ifs - so all parts of the switch will be an equal amount of instructions away.

http://en.wikipedia.org/wiki/Switch_statement#Compilation

If the range of input values is identifiably 'small' and has only a few gaps, some compilers that incorporate an optimizer may actually implement the switch statement as a branch table or an array of indexed function pointers instead of a lengthy series of conditional instructions.* This allows the switch statement to determine instantly what branch to execute without having to go through a list of comparisons.

Furthermore:

1) Don't worry about premature optimization if you haven't identified the code as a bottleneck that's slowing your program down.

2) Why does calling a function with different values make it do entirely different things? Shouldn't it be different functions, instead? (If you want to call a bunch of functions in a loop, you could always create an array of function pointers - look up function pointers)

Upvotes: 2

Sellorio
Sellorio

Reputation: 1950

I believe it could be possible to use a templated function for this.

Eg

template< int subfunc>
void func< subfunc>();

void func<1>();

Something like this should work :)

That way when you call it you say: func<1>(); and it will call the other function.

Just checked it. This solution will not work as the user wishes since the entered value in the chevrons must be a constant/compile-time resolved value.

Upvotes: 0

Israel Unterman
Israel Unterman

Reputation: 13510

Since we're tough men using C++ here, I would use a map from string (your input) to void * (represents all the functions), and this way I won't need to count on any specific order of my callable functions in the map. I also don't need to convert the input to a number (in case the input is from the console and it's a string)

#include <map>
#include <string>
#include <iostream>     // for cout

using namespace std;    // that's the way I like it

int main()
{
    map<string, void *> funcs;

    funcs["func1"] = (void *)func1;
    funcs["func2"] = (void *)func2;
    ...

    string s = myinput();
    if (funcs.find(s) != funcs.end()) {
        ((void (*)())funcs[s])();   // call the function (first casting it to the function's data type
    }
    else cout << "### Error: function " << s << " doesn't exist in map" << endl;

    return 0;
}

Upvotes: 0

Tordek
Tordek

Reputation: 10872

You could have an array of function pointers:

int foo_1() {
   cout << "One";
}

// ...

auto[] functions = {foo_1, foo_2, foo_3};

and call it with

 functions[0]();

Upvotes: 6

John Colanduoni
John Colanduoni

Reputation: 1626

When you do func(3), where the argument(s) are constant, the compiler will automatically optimize the function if it has no side effects. This means the function may not modify a global variable, member variable, or write to any pointers passed to the function. The if statements will disappear at runtime.

Upvotes: 0

Gabe Sechan
Gabe Sechan

Reputation: 93561

You can do it with value templates. But if you're doing that, why have a function at all? And why not just have N differently named functions, it will be FAR less confusing when maintaining your code.

Upvotes: -1

Related Questions