constexpr operator

Antervis
Antervis

Оператор 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())))

Для этого необходимо:

  1. все операторы внутри statement полностью определены
  2. все операторы внутри statement удовлетворяют требованиям constexpr-функций, за исключением спецификатора constexpr
  3. все аргументы функций внутри statement либо являются compile-time константами, либо рекурсивно вычислимы через constexpr(...)

Как это должно работать:

  1. все операторы внутри statement рекурсивно проверяются на вычислимость во время компиляции. То есть они должны либо соответствовать требованиям constexpr-функций (так же, как если бы они были явно помечены constexpr), либо быть контекстуально вычислимы (например, на основе контрактов).
  2. все негативные ветки if statement-ов подавляются (так, словно вместо if используется if constexpr)
  3. все аргументы функций проверяются на вычислимость на этапе компиляции
  4. вычисляется statement

Что это дает:

  1. возможность более оптимальной работы со старым кодом
  2. явное вычисление constexpr-значений
  3. возможность вычисления значений на основе контекстуальной информации
  4. возможность дополнительных оптимизаций

Пример к п.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 *) окажется вычислимым на этапе компиляции

3
рейтинг
1 комментарий
yndx-antoshkka
Здесь позарез нужна имплементация в одном из компиляторов, прежде чем начинать обсуждать подобное. Иначе - никак.
yndx-antoshkka
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).