Перенос предложения: голоса +6, -3
Автор идеи:Antervis
Оператор constexpr( statement ) -> decltype(statement) - попытаться вычислить не объявленное явно как constexpr выражение в compile-time
Оператор constexpr( statement ) -> decltype( statement ) - попытаться вычислить не объявленное явно как constexpr выражение в compile-time, либо выдать ошибку компиляции
Допустим, мы имеем простую функцию, не объявленную как constexpr:
float foo(float x, float y) {
return x*y;
}
Идея в том, чтобы иметь возможность вызвать её в constexpr-контексте (или выдать ошибку, если это невозможно):
constexpr float val1 = constexpr(foo(3,5)); // OK
int i;
cin >> i;
constexpr float val2 = constexpr(foo(4,i)); // fail: i is not compile-time constant
float bar();
constexpr float val3 = constexpr(foo(7,bar())); // fail: bar is declared, but not defined
float baz() { return 15.2; } // note: baz() is not marked as constexpr
constexpr float val4 = constexpr(foo(2,baz())); // OK, same as constexpr(foo(2,constexpr(baz())))
Для этого необходимо:
все операторы внутри statement полностью определены
все операторы внутри statement удовлетворяют требованиям constexpr-функций, за исключением спецификатора constexpr
все аргументы функций внутри statement либо являются compile-time константами, либо рекурсивно вычислимы через constexpr(...)
Как это должно работать:
все операторы внутри statement рекурсивно проверяются на вычислимость во время компиляции. То есть они должны либо соответствовать требованиям constexpr-функций (так же, как если бы они были явно помечены constexpr), либо быть контекстуально вычислимы (например, на основе контрактов).
все негативные ветки if statement-ов подавляются (так, словно вместо if используется if constexpr)
все аргументы функций проверяются на вычислимость на этапе компиляции
вычисляется statement
Что это дает:
возможность более оптимальной работы со старым кодом
явное вычисление constexpr-значений
возможность вычисления значений на основе контекстуальной информации
возможность дополнительных оптимизаций
Пример к п.4.: например:
string str = "short str";
зная в compile-time, что Small String Optimization потенциально позволяет создать std::string из const char* длиной не более 11 символов как constexpr-значение. Но в языке нет возможности проверить аргумент runtime функции на этапе компиляции. Используя оператор constexpr() таким образом:
auto str = constexpr(string("short str"));
длина строки будет проверена на этапе компиляции, ветка с выделением памяти будет подавлена, конструктор std::string(const char *) окажется вычислимым на этапе компиляции
Перенос предложения: голоса +6, -3 Автор идеи: Antervis
Оператор constexpr( statement ) -> decltype(statement) - попытаться вычислить не объявленное явно как constexpr выражение в compile-time
Оператор constexpr( statement ) -> decltype( statement ) - попытаться вычислить не объявленное явно как constexpr выражение в compile-time, либо выдать ошибку компиляции
Допустим, мы имеем простую функцию, не объявленную как constexpr:
Идея в том, чтобы иметь возможность вызвать её в constexpr-контексте (или выдать ошибку, если это невозможно):
Для этого необходимо:
Как это должно работать:
Что это дает:
Пример к п.4.: например:
зная в compile-time, что Small String Optimization потенциально позволяет создать std::string из const char* длиной не более 11 символов как constexpr-значение. Но в языке нет возможности проверить аргумент runtime функции на этапе компиляции. Используя оператор constexpr() таким образом:
длина строки будет проверена на этапе компиляции, ветка с выделением памяти будет подавлена, конструктор std::string(const char *) окажется вычислимым на этапе компиляции