是"if constexpr"在模板之外有用吗? [英] Is "if constexpr" useful outside of templates?

查看:199
本文介绍了是"if constexpr"在模板之外有用吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图完全理解if constexpr.

我了解,如果在模板中使用if constexpr(expr)expr依赖于模板参数,那么在实例化期间,将仅实例化then/else分支之一,而另一个将被实例化被丢弃.

I understand, that if if constexpr(expr) used in a template, and expr is dependent on a template parameter, then during instantiation, only one of the then/else branches will be instantiated, the other will be discarded.

我有两个问题:

  • 是真的吗?如果expr不依赖于模板参数,那么if constexpr(expr)的任何分支都不会被丢弃?如果是,那么标准在哪里说呢?我看不出该标准在哪里有例外,只有在expr是依赖的情况下才会发生丢弃.
  • if constexpr在模板之外有用吗?如果是,请问这有什么用例?您可以举一些例子来了解它的用处吗?
  • Is it true, that if expr is not dependent on a template parameter, then no branches of if constexpr(expr) will be discarded? If yes, where does the standard say so? I don't see where the standard has the exception that discard happens only when expr is dependent.
  • Is if constexpr useful outside of templates? If yes, what are the use cases of this? Can you give some examples to understand its usefulness?

推荐答案

是真的吗,如果expr不依赖于模板参数,那么if constexpr(expr)的任何分支都不会被丢弃?如果是,那么标准在哪里说呢? […]

Is it true, that if expr is not dependent on a template parameter, then no branches of if constexpr(expr) will be discarded? If yes, where does the standard say so? […]

是的,是的.您正在寻找 [stmt.if]/2 .具体来说,这部分:

Yes, that is true. You're looking for [stmt.if]/2. Specifically this part:

[…]在封闭模板化实体的实例化过程中,如果条件在实例化后不依赖于值,则不会实例化丢弃的子语句(如果有). […]

[…] During the instantiation of an enclosing templated entity, if the condition is not value-dependent after its instantiation, the discarded substatement (if any) is not instantiated. […]

在实例化之后您最终依赖于值的情况下,我能找到的最佳示例是

The best example I could find for a case where you would end up being value-dependent after instantiation is the one given by cppreference.com:

template<class T> void g() {
    auto lm = [](auto p) {
        if constexpr (sizeof(T) == 1 && sizeof p == 1) {
           // this condition remains value-dependent after instantiation of g<T>
        }
    };
}

if constexpr在模板之外有用吗?如果可以,您可以举一些例子来了解它的用处吗?

Is if constexpr useful outside of templates? If yes, can you give some examples to understand its usefulness?

if constexpr未出现在模板内部时,所有分支将被实例化,

While all branches will be instantiated when the if constexpr does not appear inside of a template, [basic.def.odr]/10 still applies:

每个程序均应准确地包含该程序中使用的每个非内联函数或变量的一个定义,在被丢弃的语句之外; […]

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement; […]

强调我的.这实际上意味着在废弃的语句中对实体的奇数用途不算在内.例如:

emphasis mine. That effectively means that an odr-use of an entity in a discarded statement doesn't count. For example:

void blub();

constexpr bool use_blub = false;

void f()
{
    if constexpr (use_blub)
    {
        blub();
    }
}

如果条件为false,则对blub()的调用将不需要您的程序具有blub()的定义.使用普通的if,即使从未使用过该程序,仍然需要该程序在某处提供blub()的定义.因此,例如,您可以使用if constexpr在调用某些库函数和调用某些后备实现之间切换,具体取决于该库是否可用(并链接至该库).除此之外,假设如果由于if constexpr而导致无法访问的代码,编译器可能不会发出警告,就像普通的if可能会发出的代码一样.我无法使用任何实际的编译器来举例说明此事,但是…

The call to blub() will not require that your program have a definition of blub() if the condition is false. Using a normal if, the program would still be required to provide a definition of blub() somewhere, even if it is never used. So you could, e.g., use if constexpr to toggle between calling some library function and calling some fallback implementation depending on whether the library is available (and being linked to). Apart from that, hypothetically, a compiler might not warn about unreachable code if it is unreachable due to an if constexpr like it potentially would with a normal if. I couldn't come up with an example of this using any actual compiler, however…

这篇关于是"if constexpr"在模板之外有用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆