Как использовать переменную указателя с consteval в C ++ 20? - PullRequest
0 голосов
/ 25 апреля 2020

Я хочу использовать указатель переменной в выражении consteval. Точно так же:

consteval int foo(int i) { return i * i; }
consteval int bar(int* i) { return (*i) * (*i); }

int main() {
  const int const_int{8};
  const int* const_int_ptr{&const_int};

  constexpr int i = foo(const_int); //fine
  constexpr int m = bar(const_int_ptr); // does not compile

  return 0;
}

Вы можете посмотреть на сайте Godbolt , что код для bar не компилируется. Как я могу исправить код для bar?

1 Ответ

3 голосов
/ 25 апреля 2020

Во-первых, у вас просто ошибка типа. bar() занимает int*, но const_int_ptr - int const*.

Как только вы исправите это, чтобы использовать указатели на константные выражения, указатель и то, к чему он относится , также должны быть константными выражениями. Ничто из этого не является правдой прямо сейчас. Если вы сделаете указатель сам по себе constexpr, вы получите более локализованную ошибку:

<source>:7:38: error: '& const_int' is not a constant expression
    7 |   constexpr const int* const_int_ptr{&const_int};
      |                                      ^~~~~~~~~~

Чтобы иметь это, адрес должен быть известен - он должен иметь c длительность хранения. Здесь указывается c правило [expr.const] / 11 :

, если значение имеет тип указателя, оно содержит адрес объекта со значением c продолжительность хранения, адрес после конца такого объекта ([expr.add]), адрес не немедленной функции или значение нулевого указателя,

У вас есть указатель на const_int, который не имеет установленной c длительности хранения, поэтому его нельзя использовать в постоянном выражении. Сделайте const_int переменную static constexpr, сделайте также сам указатель constexpr (и исправьте сигнатуру bar), и вы можете go: demo .

...