gez*_*eza 7 c++ constexpr c++17 if-constexpr template-instantiation
我想if constexpr完全理解.
我理解,如果if constexpr(expr)在模板中使用,并且expr依赖于模板参数,那么在实例化期间,只有一个then/ else分支将被实例化,另一个将被丢弃.
我有两个问题:
expr不依赖于模板参数,那么if constexpr(expr)将不会丢弃任何分支?如果是,标准在哪里这样说?我没有看到标准有什么例外,丢弃只在expr依赖时发生.if constexpr模板以外有用吗?如果是,这有什么用例?你能举出一些例子来了解它的用处吗?是真的,如果
expr不依赖于模板参数,那么if constexpr(expr)将不会丢弃任何分支?如果是,标准在哪里这样说?[...]
是的,这是事实.你在找[stmt.if]/2.特别是这部分:
[...]在封闭模板化实体的实例化期间,如果条件在实例化后不依赖于值,则不会实例化丢弃的子语句(如果有的话).[...]
对于在实例化后最终会依赖于值的情况,我能找到的最好的例子是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>
}
};
}
Run Code Online (Sandbox Code Playgroud)
为
if constexpr模板以外有用吗?如果是,您能举一些例子来了解它的用处吗?
虽然所有分支都if constexpr不会在模板内部出现时进行实例化,但[basic.def.odr]/10仍然适用:
每个程序应该只包含每个非内联函数或变量的一个定义,该函数或变量在废弃语句之外的程序中使用.[...]
强调我的.这实际上意味着废弃语句中的实体的使用不计算在内.例如:
void blub();
constexpr bool use_blub = false;
void f()
{
if constexpr (use_blub)
{
blub();
}
}
Run Code Online (Sandbox Code Playgroud)
调用blub()不会要求您的程序定义blub()条件是否为假.使用普通if程序,程序仍然需要提供blub()某个地方的定义,即使它从未使用过.因此,您可以使用if constexpr在调用某些库函数和调用某些回退实现之间切换,具体取决于库是否可用(以及链接到).除此之外,假设编译器可能不会警告无法访问的代码,如果由于if constexpr它可能与正常情况相似而无法访问if.我无法用任何实际的编译器提出这个例子,但是......
| 归档时间: |
|
| 查看次数: |
255 次 |
| 最近记录: |