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

If there's an if-constexpr, how come there's no switch-constexpr?

在 C++17 中,if constexpr was introduced; however, there doesn't seem to be a switch constexpr (see here)。这是为什么?也就是说,如果编译器支持 if constexpr,那么它支持 switch constexpr 是否也不是微不足道的(最坏的情况是作为一个 if-then-else-if-etc. 链,或者带有一些标志的多个 if控制掉落)?

我不是权威,但是如果你看一下selection statements if 有明显的真假区分,switch 没有。

我认为从评估中丢弃 switch 未使用的部分会相对困难一些,尤其是因为它们可能会失败。

如果您想保持 switch 的所有(奇异)功能,将 switch 重新实现为 if-else-if 并不是那么简单。

考虑以下来自 的示例(关于优化的 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 对我来说没有多大意义。如果有的话,它需要另一种语法(有点像我的例子),我不确定它是否有用。确实没必要。

if constexpr was ultimately derived from a more sane form of the static if concept。由于这种推导,标准委员会似乎没有考虑将相同的想法应用于 switch。所以这可能是主要原因:没有人将它添加到论文中,因为它是一种语法的限制形式,其中 switch 没有意义。

话虽这么说,switch 有很多包袱。最值得注意的一点是自动 fallthrough 行为。这使得定义其行为有点问题。

看,if constexpr 的强大功能之一是在某些条件下可以丢弃编译时未采用的一侧。这是语法的重要部分。因此,假设的 switch constexpr 应该具有类似的权力。

这对于 fallthrough 来说要难得多,因为 case 块不像 if 语句的两个块那样根本不同。特别是如果你有条件失败。现在,您可以使 switch constexpr 没有自动 fallthrough(或根本没有 fallthrough),以便不同的部分是不同的。但是你已经巧妙地改变了语法的工作方式; switch 的非 constexpr 形式与 constexpr 形式的行为不同。这样不好。

是的,如果不在标签之间放置 break; 语句,可能会导致编译错误。

请注意,两个主要的模式匹配建议 P1308 and P1260,特别是 避免 使用 switch,而是发明一个新关键字。他们都有 constexpr 个方面,但他们非常清楚地表明他们不是 switch/case