在C ++ 17中,引入了if constexpr
;但是,似乎没有switch constexpr
(请参阅here)。这是为什么?也就是说,如果编译器支持if constexpr
,那么它支持switch constexpr
也是一件容易的事(最糟糕的是,如果是if-then-else-if-etc。链,或者多个if带有某些标志)来控制失败)?
答案 0 :(得分:13)
if constexpr
最终源自more sane form中的static if
concept。因此,标准委员会似乎未考虑将相同的想法应用于switch
。因此,这可能是主要原因:没有人将其添加到论文中,因为这是switch
的语法的一种受限形式。
话虽这么说,switch
里面有很多行李。最值得注意的是自动掉线行为。这使得定义其行为有点麻烦。
请参见,if constexpr
的权力之一是在某些条件下丢弃在编译时未使用的那一侧。这是语法的重要部分。因此,假设的switch constexpr
具有类似的功效。
这与故障转移要困难得多,因为case
块在本质上不像if
语句的两个块那样明显。特别是如果您有有条件掉线。现在,您可以使switch constexpr
没有自动穿通(或完全不穿通),以便使不同的部分区分开。但是,然后您已经巧妙地更改了语法的工作方式。 constexpr
的非switch
形式的行为与constexpr
形式不同。那不好。
是的,如果不在标签之间放置break;
语句,可能会导致编译错误。
请注意,两个主要的模式匹配提议P1308和P1260,特别是 avoid 使用switch
,而不是发明一个新的关键字。他们俩都有constexpr
方面,但是他们很清楚地表明他们不是switch/case
。
答案 1 :(得分:0)
我不是权威人士,但是如果您查看selection statements if
在正确和错误陈述之间有清晰的区分,switch
则没有。
我认为要从评估中丢弃开关的未使用部分相对困难,尤其是因为它们可能会掉线。
如果要维护switch
的所有(特殊)功能,将if-else-if
重新实现为unescape(document.cookie.split('; '));
并不是那么简单。
答案 2 :(得分:0)
请考虑以下the answer to another question中的示例(关于优化的if
分支)。
struct Cat { void meow() { } };
struct Dog { void bark() { } };
template <typename T>
void pet(T x)
{
if(std::is_same<T, Cat>{}){ x.meow(); }
else if(std::is_same<T, Dog>{}){ x.bark(); }
}
pet(Cat{});
pet(Dog{});
您不能使用开关来复制它,因为您将需要使case值成为实际类型。如下所示,由于明显的原因,这是不可能的。
template <typename T>
void pet(T x)
{
switch (T) {
case Cat:
x.meow();
break;
case Dog:
x.meow();
break;
}
}
此示例是if constexpr
之类的原因:比较类型或不只是一组值的其他内容。因此,switch constexpr
对我来说意义不大。如果有的话,它将需要另一种语法(类似于我的示例),并且我不确定这将是有益的。当然没有必要。