3

I'm trying to change some macros (we have a bunch of them) for function templates. Many times, I have the following scenario:

#include <iostream>

void function_A( void )
{
    std::cout << "function A" << std::endl;
}

void function_B( void )
{
    std::cout << "function B" << std::endl;
}

#define FOO( _bar ) \
do { \
    /* ... do something */ \
    function_##_bar(); \
    /* ... do something */ \
} while( 0 )

int main() 
{
    FOO( A );
    FOO( B );
}

How can I express FOO as a function template and achieve the same result?

I am thinking in something like:

template < ??? _bar >
void foo()
{
   // somehow link function_X and _bar
}

Performance is a must!!

Thanks in advance.

Albert
  • 169
  • 2
  • 7

3 Answers3

3

You could use a case statement as in Zenith's answer, but you can do it at compile-time with templates like this:

enum class FunctionOverload
{
    A, B
};

template <FunctionOverload T>
void function();

template<>
void function<FunctionOverload::A>()
{
    std::cout << "function A" << std::endl;
}

template<>
void function<FunctionOverload::B>()
{
    std::cout << "function B" << std::endl;
}

template <FunctionOverload T>
void foo()
{
    //do stuff
    function<T>();
    //do more stuff
}

int main() 
{
    foo<FunctionOverload::A>();
    foo<FunctionOverload::B>();
}
TartanLlama
  • 63,752
  • 13
  • 157
  • 193
  • 1
    You don't even need the do/while: That's just trickery to make sure the original macro doesn't change the meaning of surrounding code. – Mark B Mar 05 '15 at 15:23
2

You actually can't do string pasting like that with templates. There may be a better way to solve your real problem, but the most straightforward way I can think of to solve your stated question is to pass the address of the function to the template (this has the further advantage that you aren't limited to functions, you can pass anything that can be called with no parameters):

template <typename Callable>
void foo(Callable func)
{
    // Stuff
    func();
}

int main() 
{
    foo(&function_a);
    foo(&function_b);
}
Mark B
  • 95,107
  • 10
  • 109
  • 188
1

I don't think you need a function template for that. Here's one solution:

enum foo { A, B };

void CallFunction(foo f)
{
    switch(f)
    {
        case A: function_A(); break;
        case B: function_B(); break;
    }
}
...
int main()
{
    CallFunction(A);
    CallFunction(B);
}
Emil Laine
  • 41,598
  • 9
  • 101
  • 157