c++ - C++ 中 If constexpr 的行为
问题描述
即使有很多关于这个话题的问题,我的问题也越来越多。我认为问题在于理解某些单词的含义。以下所有报价均来自Cppreference
- 以下文字中的“丢弃”是什么意思?我将“丢弃”理解为从未编译/触摸过的东西,无论它是什么(比如可能是错误的随机字符),它都不会干扰程序的其余部分。
在 constexpr if 语句中,条件的值必须是 bool 类型的上下文转换的常量表达式(C++23 前)一个上下文转换为 bool 的表达式,其中转换是常量表达式(C++23 起)。如果值为 true,则丢弃 statement-false(如果存在),否则丢弃 statement-true。
- “实例化”是什么意思?
如果 constexpr if 语句出现在模板化实体中,并且 if 条件在实例化后不依赖于值,则在实例化封闭模板时不会实例化丢弃的语句。
- “检查”是什么意思?我了解“已检查”意味着代码已完全编译并验证当时是否存在任何可能的错误。
在模板之外,完全检查丢弃的语句。如果 constexpr 不能替代 #if 预处理指令:
解决方案
考虑这个例子:
#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")
是一个错误。不过,模板没问题。
- “实例化”是什么意思?
模板在(2)
. foo
只是一个模板,实例化它会产生一个foo<int>
您可以调用的函数。
- 以下文字中的“丢弃”是什么意思?
实例化时丢弃真分支foo<int>
(因为条件为false
)。因此,即使int
没有find
方法,代码编译也不会出错。
现在考虑这个类似但非常不同的例子:
#include <iostream>
int main () {
int x = 0;
if constexpr (true) {
std::cout << x;
} else {
x.find("asd");
}
}
- “检查”是什么意思?
文本有点做作,它说在上面的示例中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");
| ^~~~
即使该语句从未被执行,它也必须是有效的代码。
推荐阅读
- c# - 为什么我的checkedListBox 在C# 中抛出NullReferenceException?
- ag-grid - ag-grid:需要将多个字段聚合到一个单元格内的表格中
- r - 在 R 中添加时间
- python - 当前事务发生错误。在“原子”块结束之前,您无法执行查询
- python - Python tkinter 无法将滚动条添加到嵌入画布中的图形
- python - 如何从主机 windows PC 到 VM Centos7 获取多播数据包?
- android - 谷歌签名认证错误
- mysql - 在同一个查询 MySQL 上选择 Distinct 和 Count
- node.js - GraphQL 查询在 node-georedis API 回调完成之前返回数据(异步问题?)
- python - 高效分组到 dict