问题描述
我正试图完全理解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 ofif 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 whenexpr
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?
推荐答案
是的,是的.您正在寻找 [stmt.if]/2 .具体来说,这部分:
Yes, that is true. You're looking for [stmt.if]/2. Specifically this part:
在实例化之后您最终依赖于值的情况下,我能找到的最佳示例是 cppreference.com :
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
未出现在模板内部时,所有分支将被实例化, [basic.def.odr]/10 仍然适用:
While all branches will be instantiated when the if constexpr
does not appear inside of a template, [basic.def.odr]/10 still applies:
强调我的.这实际上意味着在废弃的语句中对实体的奇数用途不算在内.例如:
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"在模板之外有用吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!