Связано: Функция, возвращающая constexpr, не компилируется
Мне кажется, что constexpr ограничена в полезности в C ++ 11 из-за невозможности определить две функции, которые в противном случае имели бы одинаковую сигнатуру, но одна из которых была constexpr, а другая не constexpr. Другими словами, было бы очень полезно, если бы у меня был, например, конструктор constexpr std :: string, который принимает только аргументы constexpr, и конструктор std :: string, не являющийся constexpr, для аргументов, не являющихся constexpr. Другим примером может быть теоретически сложная функция, которую можно было бы сделать более эффективной, используя состояние. Вы не можете легко сделать это с помощью функции constexpr, поэтому у вас есть два варианта: иметь функцию constexpr, которая очень медленная, если вы передаете аргументы, не являющиеся constexpr, или полностью отказаться от constexpr (или написать две отдельные функции, но вы можете не знать, какую версию вызывать).
Поэтому мой вопрос таков:
Возможно ли, чтобы реализация C ++ 11, соответствующая стандарту, разрешила перегрузку функций на основе аргументов constexpr, или это потребует обновления стандарта? Если это не разрешено, было ли это сделано намеренно?
@NicolBolas: Скажем, у меня есть функция, которая отображает enum
на std::string
. Самый простой способ сделать это, если предположить, что мой enum
идет от 0
до n - 1
, - это создать массив размером n
, заполненный результатом.
Я мог бы создать static constexpr char const * []
и построить std::string
при возврате (оплачивая стоимость создания объекта std::string
каждый раз, когда я вызываю функцию), или я могу создать static std::string const []
и вернуть значение, которое я ищу, оплатив стоимость всех std::string
конструкторы при первом вызове функции. Похоже, что лучшим решением было бы создать std::string
в памяти во время компиляции (аналогично тому, что делается сейчас с char const *
), но единственный способ сделать это - предупредить конструктор о том, что у него есть constexpr
аргументов.
Для примера, отличного от конструктора std::string
, я думаю, довольно просто найти пример, в котором, если вы можете игнорировать требования constexpr
(и, таким образом, создать функцию, отличную от constexpr
), вы могли бы создать более эффективную функцию. Рассмотрим эту тему: constexpr question , почему эти две разные программы запускаются с g ++ за разное время?
Если я вызываю fib
с аргументом constexpr
, я не могу победить лучше, чем компилятор, полностью оптимизирующий вызов функции. Но если я вызываю fib
с аргументом, отличным от constexpr
, я могу захотеть, чтобы он вызывал мою собственную версию, которая реализует такие вещи, как мемоизация (которая требует состояния), поэтому я получаю время выполнения, подобное тому, которое было бы моим временем компиляции, если бы я пропустил constexpr
аргумент.
constexpr
функции с непостоянными аргументами. - person Kerrek SB   schedule 20.01.2012std::string
не может иметь конструктора constexpr (за исключением конструктора, который не принимает параметры), потому что он должен выделить память для строки. Даже при оптимизации с использованием небольших строк существует возможность выделения. У вас есть пример теоретически сложной функции, которую можно было бы сделать более эффективной с помощью состояния? - person Nicol Bolas   schedule 20.01.2012We don’t propose to make constexpr applicable to function arguments because it would be meaningless for non-inline functions (the argument would be a constant, but the function wouldn’t know which) and because it would lead to complications of the overloading rules (can I overload on constexpr-ness? — no).
- person Jesse Good   schedule 20.01.2012if (is_constexpr (value)) static_assert (condition); else assert (condition);
- person David Stone   schedule 03.04.2012if (is_constexpr (value)) static_assert (condition); else assert (condition);
Устранение мертвого кода таким образом не работает. - person Tomilov Anatoliy   schedule 22.05.2013static if
или как вы хотите это назвать. Конечно, даже если бы у нас былоstatic if
, я не мог бы использоватьstatic_assert
, потому что, хотя я проверил, чтоcondition
являетсяconstexpr
,static_assert
не знает, что я это сделал, и он все равно не компилируется. - person David Stone   schedule 26.05.2013std::is_constant_evaluated()
см. Ответ на вопрос: Возможно ли is_constexpr в C ++ 11? - person Amir Kirsh   schedule 31.05.2021