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

How do i make the preprocessor take template parameters?

我正在尝试对代码进行更优化,我发现如果我将一个动作分成两部分,程序会 运行 快 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)

How do I make the preprocessor take template parameters?

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

So, how can I do this?

另外,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";
    }
} 

混合预处理器和 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
true
true