如果有一个if-constexpr,那为什么没有switch-constexpr?

时间:2018-11-19 16:42:57

标签: c++ c++17 c++20 if-constexpr

在C ++ 17中,引入了if constexpr;但是,似乎没有switch constexpr(请参阅here)。这是为什么?也就是说,如果编译器支持if constexpr,那么它支持switch constexpr也是一件容易的事(最糟糕的是,如果是if-then-else-if-etc。链,或者多个if带有某些标志)来控制失败)?

3 个答案:

答案 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;语句,可能会导致编译错误。

请注意,两个主要的模式匹配提议P1308P1260,特别是 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对我来说意义不大。如果有的话,它将需要另一种语法(类似于我的示例),并且我不确定这将是有益的。当然没有必要。