Можно ли вызвать функцию consteval с неконстантным ссылочным параметром?

#c #c 20 #consteval

Вопрос:

Если я immediate functions правильно понял правила, то следующее является законным использованием:

 consteval void func(intamp; a) { /* Anything here... */ }
 

Можно ли вызвать эту функцию? Я не мог найти никакого способа сделать это, поскольку consteval это заставляет вызывать это в выражении во время компиляции, но intamp; a заставляет его быть выражением во время выполнения из-за отсутствия const . Есть ли еще какой-то способ, которого мне не хватает?

Ответ №1:

но intamp; a заставляет его быть выражением во время выполнения из-за отсутствия const

Нет, это грубое упрощение, а не то, как работает постоянная оценка. В рамках оценки мы можем использовать движущиеся части (неконстантные объекты). До тех пор, пока они подчиняются строгому набору правил, которые проверяются при вычислении постоянного выражения. Например:

 consteval void func(intamp; a) { a = 2; }
consteval int func2() { int b = 0; func(b); return b; }

int arr[func2()];
 

Это довольно запутанный способ возврата 2 для размера массива, но он демонстрирует концепцию и одно из вышеупомянутых правил. Выполняя постоянную оценку, мы ввели вспомогательную переменную b . Затем мы что-то сделали с ним, изменили его и вернули результат. Это часть «оценки».

Бит «константа» находится в выражении, которое действительно поддается оценке во время перевода, все его «входные данные» являются постоянной времени компиляции (бессмысленно). И любые неконстантные объекты, которые мы использовали, появились только во время оценки, прожив не дольше, чем до ее завершения.

Ответ №2:

  1. Если int amp;a он не используется, то не имеет значения, что вы ему передаете. То же самое относится и к constexpr функциям.
  2. Если вы читаете/записываете int amp;a , то ваша функция может быть использована только из какой-либо другой consteval функции. Пример:
     consteval void func(int amp;x)
    {
        x  ;
    }
    
    consteval int foo(int x)
    {
        func(x);
        return x;
    }
     
  3. Если вы просто возьмете адрес int amp;a , то ваша функция будет работать при указании ссылки на глобальный или static объект.