Is “if constexpr” useful outside of templates?

时光怂恿深爱的人放手 提交于 2021-02-18 22:51:52

问题


I'm trying to understand if constexpr fully.

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.

I've got two questions:

  • 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?

回答1:


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? […]

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

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

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

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…



来源:https://stackoverflow.com/questions/53585634/is-if-constexpr-useful-outside-of-templates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!