如果constexpr vs如果常量

dab*_*ues 3 c++ optimization constexpr if-constexpr

如这个问题所示:link,如果两个if分支都有效,则两者之间没有区别:

const int foo = 5;
if (foo == 5)
{
    ...
}
else 
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

const int foo = 5;
if constexpr (foo == 5)
{
    ...
}
else 
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

在优化方面(在两种情况下else都不会实例化分支)。因此,如果if可以在编译时检查vanilla中的表达式(它涉及到constconstexpr),那么优化也可以在此处进行。

我以前认为这是的目的if constexpr,但我错了。那么,除了用例之外,还有没有if constexpr其他用例,那么我们可能只有许多if分支有效之一?

for*_*818 7

有点人为的例子,但是考虑一下:

const int foo = 6;
if (foo == 5)
{
    some_template_that_fails_to_compile_for_anything_else_than_5<foo>();
}
Run Code Online (Sandbox Code Playgroud)

即使if无法执行主体,也不会编译!编译器仍然必须发出错误。另一方面,这

const int foo = 6;
if constexpr (foo == 5)
{
    some_template_that_fails_to_compile_for_anything_else_than_5<foo>();
}
Run Code Online (Sandbox Code Playgroud)

很好,因为编译器在编译时知道的值,foo因此不会理会的主体if


Lig*_*ica 6

if constexpr 在这方面有点令人困惑。

不能确保无法访问的分支得到优化(无论如何通常都会发生)。

如果编译错误取决于模板参数,可以使用它来编写在不破坏构建的情况下无法编译的代码。全部与模板实例化有关。

所以:

template <typename T>
void foo(T x)
{
   if constexpr (std::is_same_v<T, int>)
   {
       // Code that's semantically invalid for non-int can go here!
       // Naive example (though obviously this works with some non-int types too)
       x += 42;
   }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不会扩展到不依赖于T的条件,因此,如果您想这样做:

constexpr bool DoThings = false;

void foo()
{
   if constexpr (DoThings)
   {
      static_assert(false);
   }
}
Run Code Online (Sandbox Code Playgroud)

……断言仍然会触发;您的程序格式错误。给出一个现实世界中的例子不一定很容易,但是当您仍然遇到意外时,这仍然是可以说的。

通常,尽量不要认为constexpr与“优化”有任何关系。它是关于构建阶段的;它是一个有时使您在模板metahackerer领域中强制某些事情“发生”的工具。实际上,这通常意味着编译时执行,但这与“优化事情”没有直接关系,并且您不应开始if constexpr四处散布,只是试图从已编译的可执行文件中删除“死”分支:您的编译器正在这样做无论如何(为什么您的代码中会有死分支?)。