c++ 编译器优化是否可以针对布尔参数生成两个版本的函数

Can c++ compiler optimization generate two versions of a function with respect to a boolean argument?

本文关键字:两个 函数 版本 参数 是否 优化 编译器 布尔 c++      更新时间:2023-10-16

我有一个函数f(int x, float y, char* z, .., bool b) .参数b仅以以下方式使用:

if (b) {
 ...
} else {
 ...
}

在函数体的各个部分。出于效率原因,我想有效地创建两个函数f0f1,其中b分别设置为 falsetrue,以避免在运行时评估条件。同时,由于f的实现相当长,我不想明确定义f0f1分开。是否有任何编译器优化功能可以在编译时自动生成这两个分支函数?

也许有更好的设计模式可以完全避免这种思路?请记住,条件b可以在大规模循环中进行评估。

模板允许分解这种代码,而 C++17 允许它与 if constexpr 一起干净利落地

template<bool b>
void f(int x, float y, char *z)
{
    // ...
    if constexpr (b)
    {
        // ...
    }
    else
    {
        // ...
    }
    // ...
}
// if you still need runtime dispatch
void f(int x, float y, char *z, bool b)
{
    return b ? f<true>(x, y, z) : f<false>(x, y, z);
}

如果没有if constexpr,不能保证运行时没有分支,但编译器可以很容易地正常完成。因此,如果您想要 C++17 之前的保证,您必须专注于发散部分

  • 按专业:

    template <bool b> void f_impl(..);
    template <> void f_impl<true>(..)  { /*..*/ }
    template <> void f_impl<false>(..) { /*..*/ }
    template<bool b>
    void f(int x, float y, char *z)
    {
        // ...
        f_impl<b>(..);
        // ...
    }
    
  • 或标记调度:

    void f_impl(std::true_type, ..)  { /*..*/ }
    void f_impl(std::false_type, ..) { /*..*/ }
    template<bool b>
    void f(int x, float y, char *z)
    {
        // ...
        f_impl(std::integral_constant<bool, b>{}..); // std::bool_constant<b> in C++17 
        // ...
    }
    

使用模板:

template<bool b>
void f(int x, float y, char *z)
{
    if (b)
    {
        ...
    }
    else
    {
        ...
    }
}
...
if (runtimeCondition)
{
    f<true>(1, 2, "");
}
else
{
    f<false>(1, 2, "");
}