Можно ли гарантировать, что функция constexpr вызывается не более одного раза во время компиляции?

Как следует из заголовка: возможно ли обеспечить вызов функции constexpr не более одного раза во время компиляции?

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


person rwols    schedule 30.01.2017    source источник
comment
выражения/функции constexpr не имеют побочных эффектов, поэтому не имеет значения, как часто они вызываются (за исключением времени выполнения/производительности). Итак, почему вы хотите убедиться, что constexpr оценивается только один раз?   -  person Werner Henze    schedule 30.01.2017
comment
@WernerHenze Так почему вы хотите, чтобы constexpr оценивался только один раз? просто любопытство и найти границы языка :-)   -  person rwols    schedule 30.01.2017
comment
@rwols: проблема в том, что вызов только один раз является бессмысленной концепцией для функции constexpr во время компиляции. Его буквально можно назвать полуторакратным (!) — реализации могут кэшировать оценку выражений constexpr, и это может включать в себя частичное кэширование.   -  person MSalters    schedule 30.01.2017
comment
если вы используете предварительно скомпилированные заголовки и запускаете функцию constexpr как: constexpr auto result = function(args...); в заголовке, то, возможно, компилятор вычислит ее только один раз   -  person Andrei R.    schedule 31.01.2017


Ответы (1)


Короткий ответ: нет, поскольку constexpr функции не могут читать/устанавливать внешнее состояние. (У них может быть внутреннее состояние, но они все равно должны быть "чистыми").


Настоящий ответ: возможно, да, но это плохая идея. В блоге Filip Roséen есть серия сообщений, посвященных реализации функций constexpr с отслеживанием состояния путем злоупотребления friendship и ADL:

Техника очень загадочная и сложная. Группа CWG считает это злоупотреблением функциями, и пытается сделать его неправильным с ошибкой № 2118.

person Vittorio Romeo    schedule 30.01.2017
comment
Эти три статьи хорошо читаются, так что +1 от меня! Вероятно, вы правы в том, что никто никогда не должен использовать эти методы. - person rwols; 30.01.2017
comment
(ОЧЕНЬ КРИКЛИЧНЫЕ) ссылки мертвы - person underscore_d; 12.07.2017
comment
@underscore_d: спасибо, надеюсь, они скоро вернутся. Добавлена ​​ссылка на кеш Google - person Vittorio Romeo; 12.07.2017