如何使预处理器采用模板参数?

时间:2019-08-25 02:27:16

标签: c++ c-preprocessor

我正在尝试对代码进行优化,如果我将动作分为两部分,以防程序员希望以true或false来运行该方法,我发现该程序的运行速度将提高10%。为此:

template<bool way> void action(){
    #if way
    cout << "Do true actions" << endl;
    #else
    cout << "Do false actions" << endl;
    #endif // way
}

int main()
{
    action<true>();
    action<false>();
    return 0;
}

但是,当我编译此代码时,它会打印:

Do false actions
Do false actions

当然,执行此操作的一种方法是执行2个不同的函数,但是在我的代码中,这将显着增加仅一个布尔值的函数数量。 那么,我该怎么做呢? (将模板的参数传递给预处理程序#if)

2 个答案:

答案 0 :(得分:1)

  

如何使预处理器采用模板参数?

抱歉,没有。你不能那样做。

  

那我该怎么办?

或者,C ++确实为您提供了一种称为SFINAE的方法,使您可以在编译时评估代码,如下所示:

template<bool way>
std::enable_if_t<way> action()
{
    std::cout << "Do true actions\n";
} 

template<bool way>
std::enable_if_t<!way> action()
{
    std::cout << "Do false actions\n";
} 

int main()
{
    action<true>();
    action<false>();
}

在C ++ 17中,您可以使用if constexpr,它与上面的上一个示例等效,但更具表达性和直观性:

template<bool way>
void action()
{
    if constexpr (way)
    {
        std::cout << "Do true actions\n";
    }
    else
    {
        std::cout << "Do false actions\n";
    }
} 

答案 1 :(得分:1)

混合预处理器和C ++通常不是可行的方法。
您可以引入带有bool参数的模板,然后专门处理true和false。

#include <iostream>

using namespace std;

template<bool way> void action(void)
{
    cout << "neither true nor false" << endl;
    // does not get called, not even for "2",
    // because bool ensures false or true
}

template<> void action<false>(void)
{
    cout << "false" << endl;
}

template<> void action<true>(void)
{
    cout << "true" << endl;
}

int main()
{
    action<false>();
    action<true>();
    action<2>(); // true, forced by using bool instead of int as parameter
    return 0;
}

输出:

  

false
  真实
  真实