Если есть if-constexpr, почему не существует switch-constexpr?

В C++17 if constexpr был представлен; тем не менее, кажется, нет switch constexpr (см. здесь). Это почему? То есть, если компилятор поддерживает if constexpr Разве это не тривиально, чтобы поддержать switch constexpr (в худшем случае в виде цепочки if-then-else-if-etc. или несколько if с некоторыми флагами для контроля прохождения)?

3 ответа

Решение

if constexpr в конечном итоге был получен из более вменяемой формы static if концепция Из-за этого происхождения, применяя ту же идею к switch по-видимому, не был рассмотрен комитетом по стандартам. Так что это, вероятно, основная причина: никто не добавил ее в статью, поскольку это была ограниченная форма синтаксиса, где switch не было бы смысла.

Что, как говорится, switch в нем много багажа. Наиболее заметным моментом является автоматическое поведение при падении. Это делает определение его поведения немного проблематичным.

Видите, одна из сил if constexpr означает, что сторона, не занятая во время компиляции, будет отброшена при определенных условиях. Это важная часть синтаксиса. Итак, гипотетический switch constexpr можно ожидать, чтобы иметь аналогичные полномочия.

Это гораздо сложнее сделать с прорывом, так как case блоки не так принципиально различны, как два блока if заявление. Особенно, если у вас есть условное падение. Теперь вы можете сделать switch constexpr не иметь автоматического падения (или падения вообще), так что различные разделы различны. Но затем вы слегка изменили работу синтаксиса; не constexpr форма switch ведет себя иначе, чем constexpr форма. Это не хорошо.

Да, вы можете сделать это ошибка компиляции, чтобы не ставить break; заявления между метками.

Обратите внимание, что два основных предложения по сопоставлению с образцом, P1308 и P1260, специально избегают использования switch вместо того, чтобы придумывать новое ключевое слово. У них обоих constexpr аспекты, но они совершенно ясно дают понять, что они не являются switch/case,

Я не авторитетный, но если вы посмотрите на выбор заявления if имеет четкое разделение между истинными и ложными утверждениями, 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{});

Вы не можете повторить это с помощью переключателя, потому что вам нужно, чтобы значения регистра действительно были типами; что-то вроде следующего, что невозможно по понятным причинам.

template <typename T>
void pet(T x)
{
    switch (T) {
    case Cat:
        x.meow();
        break;
    case Dog:
        x.meow();
        break;
    }
}

Этот пример является своего рода причиной if constexpr: сравнение типов или других вещей, которые не являются просто набором значений. Так что switch constexpr не имеет особого смысла для меня. Во всяком случае, ему понадобится другой синтаксис (вроде моего примера), и я не уверен, что это будет полезно. Это, конечно, не нужно.

Другие вопросы по тегам