Подтвердить что ты не робот

Должны ли мы использовать constexpr везде, где можем?

Мы, очевидно, не можем сделать все constexpr. И если мы ничего не сделаем constexpr, то проблем не будет. До сих пор было написано много кода.

Но хорошо ли шутить constexpr во всем, что может иметь это? Есть ли потенциальная проблема с этим?

4b9b3361

Ответ 1

Он не будет беспокоить компилятор. Компилятор будет (или должен все равно) дать вам диагностику, когда/если вы используете ее для кода, который не соответствует требованиям constexpr.

В то же время я был бы немного нерешительным, чтобы просто похлопать его там, потому что вы могли. Несмотря на то, что это не будет/не будет беспокоить компилятор, ваша основная аудитория - это другие люди, читающие код. По крайней мере, IMO, вы должны использовать constexpr, чтобы передать им довольно конкретный смысл, и просто похлопывать его по другим выражениям, потому что вы можете ввести в заблуждение. Я думаю, что читателю было бы интересно узнать, что происходит с функцией, обозначенной как constexpr, но используется только как обычная функция времени выполнения.

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

Ответ 2

Почему я не пытаюсь попробовать constexpr при каждой возможности в виде списка и в каком-либо конкретном порядке:

  • Я не пишу однострочные функции, которые часто
  • когда я пишу однострочный файл, он обычно делегирует функцию неконференции (например, std::get появился несколько раз недавно)
  • типы, с которыми они работают, не всегда являются литералами; да, ссылки являются буквальными типами, но если упомянутый тип не является литеральным, я вообще не могу иметь экземпляр во время компиляции
  • возвращаемый тип не всегда является литералом
  • они просто не все полезны или даже значимы во время компиляции с точки зрения их семантики.
  • Мне нравится отделять реализацию от объявления

Функции Constexpr имеют так много ограничений, что они являются нишей для специального использования. Не оптимизация или желаемый супер-набор функций в целом. Когда я пишу один, это часто потому, что метафунк или обычная функция сами по себе не сократили бы его, и у меня есть особый настрой для этого. Функции Constexpr не обладают вкусом, как другие функции.

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

Ответ 3

Да. Я считаю, что такая const не всегда хорошая практика, где бы вы ни были. Например, в вашем class, если данный метод не модифицирует какой-либо член, тогда вы всегда ставите ключевое слово const в конце.

Помимо языкового аспекта, упоминание const ness также является хорошим показателем для будущего программиста/рецензента, что выражение имеет константу внутри этого региона. Это относится к хорошей практике кодирования и добавляет читаемость также. например (из @Luc)

constexpr int& f(int& i) { return get(i); }

Теперь добавление constexpr предполагает, что get() также должен быть constexpr.

Я не вижу никаких проблем или последствий из-за constexpr.

Изменить. Дополнительным преимуществом constexpr является то, что вы можете использовать их как аргумент template в некоторых ситуациях.

Ответ 4

Я склонен согласиться со Скоттом Мейерсом в этом (как и в большинстве случаев): "Используйте constexpr, когда это возможно" (из пункта 15 "Эффективного современного" C++), особенно если вы предоставляете API для использования другими. Это может быть очень разочаровывающим, если вы хотите выполнить инициализацию во время компиляции с использованием функции, но не можете, потому что библиотека не объявила об этом constexpr. Кроме того, все классы и функции являются частью API, независимо от того, используются ли они миром или только вашей командой. Так что используйте его, когда можете, чтобы расширить сферу его применения.

// Free cup of coffee to the API author, for using constexpr
// on Rect3 ctor, Point3 ctor, and Point3::operator*
constexpr Rect3 IdealSensorBounds = Rect3(Point3::Zero, MaxSensorRange * 0.8);

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