如果constexpr vs if with constant [duplicate]

问题描述 投票:3回答:2

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

const int foo = 5;
if (foo == 5)
{
    ...
}
else 
{
    ...
}

const int foo = 5;
if constexpr (foo == 5)
{
    ...
}
else 
{
    ...
}

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

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

c++ optimization constexpr if-constexpr
2个回答
7
投票

有点做作的例子,但考虑一下:

const int foo = 6;
if (foo == 5)
{
    some_template_that_fails_to_compile_for_anything_else_than_5<foo>();
}

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

const int foo = 6;
if constexpr (foo == 5)
{
    some_template_that_fails_to_compile_for_anything_else_than_5<foo>();
}

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


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;
   }
}

不幸的是,这并没有扩展到不依赖于T的条件,所以如果你想这样做:

constexpr bool DoThings = false;

void foo()
{
   if constexpr (DoThings)
   {
      static_assert(false);
   }
}

......断言仍将开火; your program is ill-formed。提出一个真实世界的例子并不一定容易让你受到这种打击,但它仍然可以说出乎意料。

一般来说,尽量不要将constexpr视为与“优化”有关。这是关于构建阶段;它是一种工具,有时可以让你在模板metahackerer的领域中强制执行某些“发生”的事情。在实践中,这通常意味着编译时执行,但它与“优化事物”并不直接相关,并且您不应该开始在任何地方使用if constexpr来尝试从已编译的可执行文件中删除“死”分支:您的编译器正在执行无论如何(为什么你的代码中有死分支?)。

© www.soinside.com 2019 - 2024. All rights reserved.