Operator as a function pointer

I would like to have an implementation of the operator() class in several different ways based on the option given in the class. Since it will be called many times, I do not want to use anything that branches. Ideally, operator() will be a function pointer that can be set using a method. However, I'm not sure what this looks like. I tried:

 #include <iostream> class Test { public: int (*operator())(); int DoIt1() { return 1; } int DoIt2() { return 2; } void SetIt(int i) { if(i == 1) { operator() = &Test::DoIt1; } else { operator() = &Test::DoIt2; } } }; int main() { Test t1; t1.SetIt(1); std::cout << t1() << std::endl; t1.SetIt(2); std::cout << t1() << std::endl; return 0; } 

I know that it will work if I create another pointer to a function and call it from the operator() function. But is it possible for the operator() function to be a function pointer? Something like what I wrote (which does not compile)?

The code above indicates:

test.cxx: 5: 21: error: Declaring 'operator () as a non-function

test.cxx: In the member function 'void Test :: SetIt (int):

test.cxx: 17: 16: error: 'operator () not defined

test.cxx: 19: 16: error: 'operator () not defined

test.cxx: In the function 'int main ():

test.cxx: 30: 19: error: no match for calling on '(Test) ()

test.cxx: 34: 19: error: no matches to call in '(Test) ()

+6
source share
3 answers

Your class must somehow remember which function pointer to use. Save it as a member of the class:

 class Test { public: Test() : func(0) {} int operator()() { // Note that pointers to Test member functions need a pointer to Test to work. return (this->*func)(); // undefined behavior if func == 0 } void SetIt(int i) { if(i == 1) { func = &Test::DoIt1; } else { func = &Test::DoIt2; } } private: int DoIt1() { return 1; } int DoIt2() { return 2; } // Typedef of a pointer to a class method. typedef int (Test::*FuncPtr)(); FuncPtr func; }; 

However, before embarking on this, first profile your code and see if branching through switch or if is really a bottleneck (it may not be so!). Modern processors have very conflicting performance characteristics, so compilers can generate more efficient code than you think. The only way to make sure that forking is actually too expensive for you is to profile your code. (And by "profiling," I mean "run well-designed experiments," rather than "come up with a hunch without testing.")

+5
source

You can make your operator() built-in function that calls another pointer. The optimizer should completely remove the extra direction.

+1
source

One solution is @In silico, which is valid in both C ++ 03 and C ++ 11.

Here is another solution for C ++ 11:

 std::function<int(Test*)> func; func = &Test::DoIt1; func(this); //this syntax is less cumbersome compared to C++03 solution 

Fast online demo

+1
source

Source: https://habr.com/ru/post/913692/


All Articles