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

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

4

Решение

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,

13

Другие решения

Я не авторитетный, но если вы посмотрите на выбор заявления if имеет четкое разделение между истинными и ложными утверждениями, switch не делает.

Я предполагаю, что было бы относительно сложнее отбросить неиспользованные части перехода от оценки, тем более что они могут провалиться.

Переопределение switch как if-else-if не все так просто, если вы хотите сохранить все его (экзотические) возможности.

0

Рассмотрим следующий пример из ответ на другой вопрос (об оптимизированном 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 не имеет особого смысла для меня. Во всяком случае, ему понадобится другой синтаксис (вроде моего примера), и я не уверен, что это будет полезно. Это, конечно, не нужно.

0
По вопросам рекламы [email protected]