Function pointers: a simple use of canonical use in terms of performance? If so, what are the 11th C ++ alternatives?

I often use function pointers in my c++code, always in accordance with this simple canonical example (for example, functions have the same I / O, but the desired operation is known only at runtime)

#include <iostream>
using namespace std;

int add(int first, int second){
    return first + second;
}
int subtract(int first, int second){
    return first - second;
}
int operation(int first, int second, int (*functocall)(int, int)){
    return (*functocall)(first, second);
}
int main(){
    int  a, b;
    int  (*plus)(int, int) = add;
    int (*minus)(int, int) = subtract;

    a = operation(7, 5, plus);
    b = operation(20, a, minus);
    cout << "a = " << a << " and b = " << b << endl;
    return 0;
}

I started using this some time ago simply because I found it easier to use. As I learn more about C ++, I wonder: is this construct bad in terms of performance in this context ? If so, why and what are the best options for c++11-ish?

, ( )

EDIT:

Im x86.

+4
5

, , , , , . - :

enum FuncTodo{
    PLUS,
    MINUS,
};

int operation(int first, int second, FuncTodo todo) {
    switch(todo) {
        case PLUS: return first + second;
        case MINUS: return first - second;
    }
}

, ( , , operation ), , .

, , . ( operation plus, "", plus add). , , , , operation, .

+3

, , - templatize; , , ; , ( ).

    template <typename Functor>
    int operation(int first, int second, Functor f)
    {
        return f(first, second);
    }

    ...

    a = operation(7, 5, std::plus<int> /* since C++14, roll your own otherwise */);
    b = operation(20, a, std::minus<int>);

, , , , short() subtract(); , ++ std:: sort C qsort .

+5

, , , (). , . , x86.

*, , , , , , ++ 11 function lambdas, , , .

, , .


* " ": (, ) . YMMV.

+2

( : ), .

, , Visual Studio, channel9.

- :

struct Operation {
    virtual int op(int first, int secont) = 0;
    virtual ~Operation() = default;
};


struct Add : public Operation {
    virtual int op(int first,  int second) {
        return first + second;
    }
    virtual ~Add() {}
};

struct Sub : public Operation {
    virtual int op(int first,  int second) {
        return first - second;
    }
    virtual ~Sub() {}
};

struct Mul: public Operation {
    virtual int op(int first,  int second) {
        return first * second;
    }
    virtual ~Mul() {}
};

int main () {
    std::unique_ptr<Operation> o = new Add;
    auto a = o(10,20);
}

, :

int main () {
    std::unique_ptr<Operation> o = new Add;
    auto a = o(10,20);
}


int main() {
    // compiler is able to prove that it will always be the Add function.
    std::unique_ptr<Add> add = new Add;
    auto a = add(10,20);
}

int main() {
    // compiler is able to prove that the scope  of add will never leave
    // main.
    Add add;
    auto a = add(10,20);
}

int main() {
    // compiler can show that inlining is faster.
    Add add;
    auto a = 10 + 20
}

, - :

int main() {
    // using profile guided optimization he might figure that the two most
    // frequent calls are to Add or Sub

    Operator *op; // is something unknown

    int a;
    if (typeid(op) == typeid(Add)) {
        a = 10 + 20;
    }
    else if (typeid(op) == typeid(Sub)) {
        a = 10 - 20;
    }
    else {
        a = op(10,20);
    }
}
+1
source

There are various methods using multi-threaded code, if you are looking at performance (not readability, maintainability, etc.) you should read this http://www.complang.tuwien.ac.at/forth/threaded-code.html about Forth and try some.

0
source

All Articles