2015-03-05 2 views
3

Я пытаюсь изменить некоторые макросы (у нас есть их) для шаблонов функций. Много раз, у меня есть следующий сценарий:C++ от макросов до шаблонов

#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); 
} 

Как я могу выразить FOO как шаблон функции и достичь того же результата?

Я имею в виду что-то вроде:

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

Performance является обязательным !!

Заранее спасибо.

+0

Вы можете разместить полный компилируемый пример исходного кода? –

+2

«Много раз, у меня есть следующий сценарий» - запах кода? –

ответ

3

Вы можете использовать случай заявление, как в ответ Zenith, но вы можете сделать это во время компиляции с помощью шаблонов, как это:

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>(); 
} 
+1

Вам даже не нужно делать/пока: Это просто обман, чтобы убедиться, что исходный макрос не меняет смысл окружающего кода. –

+0

Ах, конечно, просто вклеил его, не задумываясь. – TartanLlama

+0

Спасибо @TartanLlama !! Это то, что я искал! – Albert

1

Я не думаю, что для этого вам нужен шаблон функции. Вот одно решение:

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); 
} 
+0

Спасибо, хорошее решение, но производительность - необходимость. Мы не можем позволить себе эти филиалы. – Albert

2

Вы на самом деле не можете сделать строку склеивание с помощью шаблонов. Может быть, лучший способ решить вашу реальную проблему, но самый простой способ решить ваш заявленный вопрос - передать адрес функции в шаблон (это имеет еще одно преимущество, что вы не ограничены функции, вы можете передавать все, что может быть вызвано без параметров):

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

int main() 
{ 
    foo(&function_a); 
    foo(&function_b); 
} 
+0

Это кажется мне самым простым решением. – edmz

+0

Тем более, что вы также можете передавать другие вызовы (объекты функции, lambdas, функторы) ... – Pixelchemist

+0

Это не имеет для меня никакого смысла. Если вам нужно написать «function_a» в main(), почему бы просто не назвать его напрямую? Цель макроса FOO не вводить «function_». –

Смежные вопросы