Если есть if-constexpr, почему нет switch-constexpr? - PullRequest
0 голосов
/ 19 ноября 2018

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

Ответы [ 3 ]

0 голосов
/ 19 ноября 2018

Рассмотрим следующий пример из ответа на другой вопрос (об оптимизированных 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 голосов
/ 19 ноября 2018

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.

0 голосов
/ 19 ноября 2018

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

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

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

...