是否有任何理由只将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 ++中?
答案 0 :(得分:28)
if constexpr
被提议相对接近于最终确定的C ++ 17。
装饰(如switch
)可能推迟了它的包含。
像强制循环展开这样的花哨肯定会有。
改变C ++标准需要真正的工作。你必须自己在编译器中实现它作为证明它可以完成,说服其他编译器编写者应该很容易或值得努力,弄清楚它应该在标准中措辞明确和明确,说服其他成员委员会认为你的改变不只是语言等等。
不需要出现不的原因。事情不会一直发生。 C ++改进不是某种自然过程,除非有人阻止它,
Tl;博士:因为你没有提出建议并通过标准化来实现它。立即开始,可能是在C ++ 20中。 “我不值得”提出建议不是一个借口:这是工作需要做的事情,而不是一些非常棒的恩惠。通过做这项工作,一个人变得很棒。 “我很懒”是一个借口,一个我非常熟悉的借口。答案 1 :(得分:13)
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,则{ {1}} 已实例化。如果你想要这些语义,你需要弄清楚标准,它必须指定一个有效的程序来确定要丢弃哪些语句(请记住,这些baz<x>
和if
可以是任意嵌套)。如果您不想要这些语义,那么switch
可能不会比一堆switch constexpr
更强大,但与普通if constexpr
语句相比会有限制。
switch
进一步加剧了这些困难。现在,它可能是值得的。但有人必须付出努力。
答案 2 :(得分:0)
不是答案,但评论时间太长。您可以使用#pragma unroll
在英特尔(R)编译器中展开编译时循环。
void bar();
constexpr void foo() {
#pragma unroll(10)
for (auto i = 0; i < 10; i++) {
bar();
}
}
void baz()
{
foo();
}
关于Godbolt的Live example 证明展开。