Как использовать static_assert для следующего фрагмента кода?

101
26 февраля 2021, 22:50

Есть вот такой пользовательский литерал. Я бы хотел выкинуть предупреждение в случае если принимаемое значение не лежит в диапазоне 0..7. Могу ли я этого добиться?

constexpr unsigned char operator"" _cmd(const char command) {
      if (command == '>')
        return 0;
      else if (command == '<')
        return 1;
      else if (command == '+')
        return 2;
      else if (command == '-')
        return 3;
      else if (command == ',')
        return 4;
      else if (command == '.')
        return 5;
      else if (command == '[')
        return 6;
      else if (command == ']')
        return 7;
       else 
       static_assert(, "INVALID COMMAND");
    }
Answer 1

В данном случае похоже, что натурального решения со static_assert нет, ибо ваша функция в общем случае совсем не обязательно вычисляется во время компиляции. Однако вы можете воспользоваться хитростью и вместо static_assert использовать throw или любую другую конструкцию, которая заведомо "убивает" constexpr-ность функции

...
else if (command == ']')
  return 7;
else 
  throw 0;

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

template <unsigned char C> struct S{};
int main()
{
  S<'+'_cmd>(); // OK
  S<'/'_cmd>(); // Error
  constexpr int a = ','_cmd; // OK
  constexpr int b = ':'_cmd; // Error
}

К сожалению, в тех контекстах, где константного выражения не требуется, ошибки компиляции не будет, а будет полноценное бросание исключения во время выполнения. То есть вам, для достижения изначальной цели (ошибки компиляции при неправильном аргументе) придется самому внимательно следить за тем, чтобы литерал использовался только в контекстах, требующих константного выражения.

Answer 2

В с++ 14 должно работать.

else 
       assert(false && "INVALID COMMAND");

При этом, если assert сработает на этапе компиляции, она упадёт. P.s сам не проверял, но пруф: https://www.google.com/amp/s/akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/amp/ Там есть способ это сделать и на с++ 11

READ ALSO
Парсинг большого файла (книги)

Парсинг большого файла (книги)

ПодскажитеПарсинг работает, но очень, очень долго

114
Верстка сайта, кнопки-меню по периметру области

Верстка сайта, кнопки-меню по периметру области

Появилась проблема с версткой меню сайтаСерверная технология используемая asp

95
На веб-странице появились отступы между блоками, хотя я их не указывал

На веб-странице появились отступы между блоками, хотя я их не указывал

Как убрать отступы между блоками? Свойства padding и margin не работают

82
Парсинг сайта с помощью ehp

Парсинг сайта с помощью ehp

Как запарсить html с помощью библиотеки ehp,

125