如果有 constexpr if 语句,为什么没有其他 constexpr 语句呢?

If there's a constexpr if statement, why not other constexpr statements too?

本文关键字:语句 constexpr 其他 if 如果 为什么      更新时间:2023-10-16

有什么理由只if constexpr包含在C++17中吗?

我可以这样做:

template <int N>
constexpr int fib() {
if constexpr (N == 1 || N == 2) {
return 1;
} else {
return fib<N - 1>() + fib<N - 2>();
}
}

为什么C++委员会没有考虑switch constexpr

template <int N>
constexpr int fib() {
switch constexpr (N) {
case 1:
case 2: return 1;
default: return fib<N - 1>() + fib<N - 2>();
}
}

switch constexpr看起来凉爽多了

甚至是过早的编译时循环,不使用模板替换/递归模板函数,使用for constexpr/while constexpr展开:

constexpr void printFoo() {
for constexpr (auto i = 0; i < 10; i++) {
cout << fib<i>() << endl;
}
}

它们是否会包含在 C++20/未来版本的C++中?

if constexpr

的提出相对接近C++17正在定稿。

装饰(如switch(可能会推迟其包含。

像强制循环展开这样的花哨肯定会有。

改变C++标准需要真正的工作。 你必须在编译器中自己实现它作为可以做到的证明,说服其他编译器编写者它应该很容易或值得付出努力,弄清楚标准中的措辞应该如何清晰明确,说服委员会的其他成员你的改变不仅仅是语言上的麻烦, 等。

它不需要某事发生的理由。 事情不会一直发生。 C++改善不是除非有人阻止它,否则会发生的自然过程,

Tl;大卫:因为你没有提出它,也没有通过标准化来证明它。 今天开始,可能是在 C++20。 "我不配"提出不是借口:这是需要做的工作,而不是因为很棒而获得的福音。 一个人通过做工作变得很棒。 "我很懒"是一个借口,一个我非常熟悉的借口。

一般来说,C++标准委员会不会仅仅因为它们"看起来很酷"而添加新功能。每个新功能只有在提交论文后才会添加,该论文提出了精心设计的法律术语,精确地指定了该功能的语法和语义,由于所有含义都由专家讨论,因此通常会经过多次修订。

这为添加新功能提供了天然的障碍:如果它添加到语言中的功能不足以使这种艰苦的体验变得值得,那么没有人会费心正式提出它。

if constexpr是对语言的宝贵补充(尝试重写代码以不使用它,你就会明白为什么(,而且指定起来并不复杂:如果条件为真,则丢弃第二个子语句,否则丢弃第一个子语句。

相比之下,switch constexpr由于switch发言更加复杂,在措辞上会造成更大的困难。(不过,欢迎您尝试。例如,你对它应该如何工作有一个自然的期望:

switch constexpr (x) {
case 1:
bar<x>();
if constexpr(y) { break; }
case 2:
baz<x>();
}

也就是说,如果x为 1 并且y为真,则baz<x>不会被实例化,但如果x为 1 并且y为 false,则baz<x>实例化。如果你想要这些语义,你需要弄清楚标准,它必须指定一个有效的过程来确定要丢弃哪些语句(请记住,这些ifswitches可以任意嵌套(。如果你不想要这些语义,你的switch constexpr可能并不比一堆if constexpr更强大,但与正常的switch语句相比会有限制。

这些困难随着for constexpr而进一步增加。现在,这可能是值得的。但必须有人付出努力。

不是答案,但太长了,无法发表评论。 您可以使用#pragma unroll在英特尔(R( 编译器中展开编译时循环。

void bar();
constexpr void foo() {
#pragma unroll(10)
for (auto i = 0; i < 10; i++) {
bar();
}
}
void baz()
{
foo();
}

在Godbolt上活生生的例子来证明展开。