Каковы преимущества использования consteval вместо функции constexpr?

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

Я могу вспомнить несколько вещей:

  • читатель может просто прочитать сигнатуру функции и знать, что функция оценивается во время компиляции
  • компилятор может выдавать меньше кода, так как consteval fns никогда не используются во время выполнения (это предположение, у меня нет реальных данных по этому поводу)
  • нет необходимости иметь переменные для принудительного ctfe, пример в конце

Примечание: если качество кода слишком расплывчато, я понимаю, что некоторые люди могут захотеть закрыть этот вопрос, для меня качество кода на самом деле не такой расплывчатый термин, но...

пример, где constexpr сбой откладывается до времени выполнения:

constexpr int div_cx(int a, int b)
{ 
  assert(b!=0);
  return a/b;
}
    
int main()
{
    static constexpr int result = div_cx(5,0); // compile time error, div by 0
    std::cout << result; 
    std::cout << div_cx(5,0) ; // runtime error :( 
}

1 ответ

Чтобы иметь значимое, значимое статическое отражение (отражение во время компиляции), вам нужен способ выполнения кода во время компиляции. Первоначальное предложение TS для статического отражения использовало традиционные методы метапрограммирования шаблонов, потому что это были единственные эффективные инструменты для выполнения кода во время компиляции.

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

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

Но что, если вы хотите написать функцию, которая принимает значение отражения и возвращает значение отражения? Или список значений отражения?

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

Функция, которая принимает значение отражения, не может этого сделать. Он должен выполняться только во время компиляции. Так constexpr не подходит для таких функций.

Войти consteval: функция, которая "требуется" для выполнения только во время компиляции. Существуют особые правила, по которым указатели на такие функции не могут проникнуть в исполняемый код и так далее.

Как таковой, constevalв данный момент не имеет особой цели. Он используется в нескольких местах, например source_location::current(), который принципиально не имеет смысла выполнять во время выполнения. Но в конечном итоге эта функция является необходимым строительным блоком для дальнейших инструментов программирования времени компиляции, которые еще не существуют.

Это было изложено в документе, который изначально предлагал эту функцию:

Тем не менее, толчком к созданию настоящей статьи является работа, проделанная ИК7 в области отражения во время компиляции. В настоящее время существует общее мнение, что в будущей языковой поддержке для отражения следует использовать constexpr функций, но поскольку "функции отражения" обычно должны оцениваться во время компиляции, они, скорее всего, будут немедленными функциями.

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