【问题标题】:Behavior of If constexpr in C++C++ 中 If constexpr 的行为
【发布时间】:2021-09-21 14:23:44
【问题描述】:

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

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

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

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

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

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

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

【问题讨论】:

  • Discarded:跳过,忽略,就好像它不存在一样。
  • 实例化:在模板上下文中使用。表示使用给定的具体模板参数“体现”(实际上是定义)模板。
  • @YvesDaoust:比这更复杂,如第 2 点和第 3 点所述。“discarded” 确实误导了 IMO。
  • 检查:无论如何它必须是一个有效的声明。 (即使它可以被丢弃。)
  • 事实上,第1点区分了两个块并name不满足条件的语句/分支,然后给它一些“属性”。

标签: c++ if-statement


【解决方案1】:

考虑这个例子:

#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)
}

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

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

模板在(2) 中实例化。 foo 只是一个模板,实例化它会生成一个可以调用的函数 foo&lt;int&gt;

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

foo&lt;int&gt;被实例化时,true-branch被丢弃(因为条件是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");
      |               ^~~~

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

【讨论】:

  • 如果将您的第一个代码中的 std::cout &lt;&lt; t.find("asd"); 更改为 whatever contains errors 怎么办?
  • @Roman 然后是一样的。 std::cout foo<int>() 编译。只有当 T == std::string 时,真正分支中的代码才不会被丢弃和检查
猜你喜欢
  • 2021-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-10
  • 2016-11-13
  • 2020-02-19
  • 2017-09-12
相关资源
最近更新 更多