首页 > 解决方案 > C++ 中 If constexpr 的行为

问题描述

即使有很多关于这个话题的问题,我的问题也越来越多。我认为问题在于理解某些单词的含义。以下所有报价均来自Cppreference

  1. 以下文字中的“丢弃”是什么意思?我将“丢弃”理解为从未编译/触摸过的东西,无论它是什么(比如可能是错误的随机字符),它都不会干扰程序的其余部分。

在 constexpr if 语句中,条件的值必须是 bool 类型的上下文转换的常量表达式(C++23 前)一个上下文转换为 bool 的表达式,其中转换是常量表达式(C++23 起)。如果值为 true,则丢弃 statement-false(如果存在),否则丢弃 statement-true。

  1. “实例化”是什么意思?

如果 constexpr if 语句出现在模板化实体中,并且 if 条件在实例化后不依赖于值,则在实例化封闭模板时不会实例化丢弃的语句。

  1. “检查”是什么意思?我了解“已检查”意味着代码已完全编译并验证当时是否存在任何可能的错误。

在模板之外,完全检查丢弃的语句。如果 constexpr 不能替代 #if 预处理指令:

标签: c++if-statement

解决方案


考虑这个例子:

#include <iostream>
#include <string>

template <typename T>
void foo() {
    T t;
    if constexpr (std::is_same_v<T,std::string>){
        std::cout << t.find("asd");
    } else {
        t = 0;
        std::cout << t;
    }
}

int main () {
    foo<int>();                     // (2)
}

WhenT是一个没有find方法的类型,那么std::cout << t.find("asd")是一个错误。不过,模板没问题。

  1. “实例化”是什么意思?

模板在(2). foo只是一个模板,实例化它会产生一个foo<int>您可以调用的函数。

  1. 以下文字中的“丢弃”是什么意思?

实例化时丢弃真分支foo<int>(因为条件为false)。因此,即使int没有find方法,代码编译也不会出错。

现在考虑这个类似但非常不同的例子:

#include <iostream>

int main () {
    int x = 0;
    if constexpr (true) {
        std::cout << x;
    } else {
        x.find("asd");
    }
}
  1. “检查”是什么意思?

文本有点做作,它说在上面的示例中false分支被丢弃,但仍然检查它,因为它在模板之外。这只是英文术语:“checked”表示编译器检查代码是否正确。int没有方法find,因此上述导致错误:

<source>:8:15: error: request for member 'find' in 'x', which is of non-class type 'int'
    8 |             x.find("asd");
      |               ^~~~

即使该语句从未被执行,它也必须是有效的代码。


推荐阅读