c++ - C++ 中 if/else 分支的编译时消除

标签 c++ templates language-lawyer compiler-optimization template-specialization

在以下代码示例中,if声明取决于 bool模板参数,它是一个编译时常量。编译器以不同的方式处理此代码:

  • MSVC 因链接错误而失败(这是我所期望的),因为 else 中的模板函数分支缺乏对 true 的特化模板参数值(即使它从未被调用过)。
  • GCC 和 Clang 编译时都没有问题,并且运行时行为是正确的。这显然是因为他们评估了 if在编译时声明并在链接之前删除未使用的分支。

  • 问题是哪种行为符合标准(或者它是未定义的行为并且两者都以自己的方式正确)?
    #include <iostream>
    
    template<const bool condition>
    struct Struct
    {
        void print()
        {
            if (condition)
            {
                std::cout << "True\n";
            }
            else
            {
                printIfFalse();
            }
        }
    
    private:
        void printIfFalse();
    };
    
    template <>
    void Struct<false>::printIfFalse()
    {
        std::cout << "False\n";
    }
    
    int main()
    {
        Struct<true> withTrue{};
        withTrue.print();
    
        Struct<false> withFalse{};
        withFalse.print();
    
        return 0;
    }
    

    最佳答案

    所有编译器的行为都正确。

    您的程序格式错误,不需要诊断,因为您使用的是 odr Struct<true>::printIfFalse通过 Struct<true>::print() 的实例化需要来自 withTrue.print(); 中的调用.在丢弃语句之外使用 odr 的函数必须在程序中有定义,参见 [basic.def.odr]/4 ,否则程序格式错误,无需诊断。

    如果你使用 if constexpr,你会得到一个废弃的语句。在模板中,并且语句不在所选分支中。因此,您可以使用 if constexpr 来使程序格式良好。而不是 if .这是一个 C++17 特性。

    关于c++ - C++ 中 if/else 分支的编译时消除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60885314/

    相关文章:

    c++ - 如何设置 OpenGL 版本?

    c++ - 我应该让我的 MutexLock 易变吗?

    c++ - 将类型说明符传递给模板函数

    c++11随机数生成: how to re-implement `uniform_int_distribution` with `mt19937` without templates

    c++ - NaN 上的飞船运算符(operator)

    c++ - 为什么我必须提供 'operator ==' 当 'operator <=>' 就足够了?

    c++ - 错误: redefinition of function template (or C2995)

    c++ - 在 QT Creator 中更改按钮的颜色

    c++ - 当库使用模板(泛型)时,是否可以使用 Rust 的 C++ 库?

    c++ - C++14 中 main() 的合法定义