Мой фактический вариант использования немного сложен, но его можно резюмировать следующим образом:
Код: Выделить всё
#include
#include
template
constexpr double create_val(T x)
{
// some code that can be constant evaluated or not, according to T
}
int main() {
constexpr_if_possible auto v = create_val(4);
// w can only be constexpr under certain conditions
// otherwise it should be at least const
constexpr_if_possible auto w = create_val(4.0);
return static_cast(v*w);
}
Вот пример, иллюстрирующий это:
Код: Выделить всё
#include
#include
template
constexpr double create_val(T x)
{
static_assert(std::is_arithmetic_v);
if constexpr (std::is_integral_v)
{
// some leggit code in constant expression
// only an example
return static_cast(x*x);
}
else
{
// some not usable code in constant expression
// only an example
return std::sqrt(x);
}
}
int main() {
// constexpr_if_possible is equivalent to constexpr here
constexpr auto v = create_val(4);
// conditions are not met, constexpr_if_possible is equivalent to const
const auto w = create_val(4.0);
return static_cast(v*w);
}
Код: Выделить всё
constexpr
(gcc принимает ее и оптимизирует вычисления, вероятно, потому, что она уже объявляет std::sqrt как constexpr).
Live
В соответствии с аргументом шаблона create_val, инициализированная переменная может быть или не быть constexpr.
Если бы я был в функции шаблона, я мог бы использовать if constexpr, но, возможно, ценой дублирования кода.
Очевидно, я мог бы также прочитать все коды для определения «вручную», возможна ли постоянная оценка, но, как видно из моего примера, когда я изменю языковой стандарт, мне придется снова проанализировать весь мой код, чтобы увидеть, изменилась ли ситуация.Можно ли (и как) объявить v, w условно constexpr относительно их инициализатора? В псевдо-совершенно неправильном коде:
Код: Выделить всё
constexpr_if_possible auto w = create_val(...);
У меня сложилось впечатление, что синтаксис языка не может допускайте это, но есть ли какой-нибудь обходной путь?
NB. В реальном случае тип моей переменной может быть любым (фундаментальные типы, а также классы).
Подробнее здесь: https://stackoverflow.com/questions/787 ... ion-expres