【问题标题】:c++ from macros to templatesc++ 从宏到模板
【发布时间】:2015-05-07 00:30:35
【问题描述】:

我正在尝试为函数模板更改一些宏(我们有很多)。很多时候,我有以下场景:

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

性能是必须的!!

提前致谢。

【问题讨论】:

  • 你能把原始代码的完整编译示例放上去吗?
  • “很多时候,我有以下场景” - 代码异味?

标签: c++ templates macros concatenation c-preprocessor


【解决方案1】:

您可以像 Zenith 的回答那样使用 case 语句,但您可以在编译时使用这样的模板:

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

【讨论】:

  • 你甚至不需要 do/while:这只是为了确保原始宏不会改变周围代码的含义。
  • 谢谢@TartanLlama !!这就是我要找的东西!
【解决方案2】:

你实际上不能用模板做这样的字符串粘贴。可能有更好的方法来解决您的实际问题,但我能想到的解决您陈述的问题的最直接方法是将函数的地址传递给模板(这具有进一步的优势,您不仅限于函数,你可以传递任何可以不带参数调用的东西):

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

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

【讨论】:

  • 在我看来这也是最直接的解决方案。
  • 特别是因为您还可以传递其他可调用对象(函数对象、lambda、仿函数)...
  • 这对我来说毫无意义。如果你必须在 main() 中写“function_a”,为什么不直接调用它呢? FOO 宏的目的是避免键入“function_”。
【解决方案3】:

我认为您不需要为此使用函数模板。这是一个解决方案:

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

【讨论】:

  • 谢谢,很好的解决方案,但性能是必须的。我们负担不起那些分支机构。
猜你喜欢
  • 1970-01-01
  • 2012-05-18
  • 1970-01-01
  • 2010-12-04
  • 1970-01-01
  • 2018-11-16
  • 2022-01-03
  • 2011-01-26
相关资源
最近更新 更多