как гарантировать инициализацию переменной стека с постоянной времени компиляции

В C++20 у нас теперь есть . и .

Теперь я могу гарантировать, что статическая переменная инициализируется результатом функции или с помощью . В ПОРЯДКЕ

Я также могу гарантировать, что переменная стека инициализируется результатом consteval функция, выполняемая во время компиляции.

Но как я могу заставить запустить функцию для вычисления результата во время компиляции для инициализации переменной в стеке?

      // Lets assume that we have a much more complex function so that the compiler will not
// always decide to compile time evaluation automatically 
constexpr int func( int i )
{
    return i+2;
}

int main()
{
     ??? int i = func(8);
     ...
     i = 9;
}

Если мы используем переменную, она неявно константна и здесь не разрешена. Любой шанс инициализировать эту переменную с результатом оценки времени компиляции constexprфункция, не делая ее константой? мне просто интересно почему constinitограничен статическими переменными. Для моего смысла особого нет.

2 ответа

Я думаю, что лучше использовать constevalфункцию, но если вы не можете ее изменить, вы можете просто использовать временную переменную, которая обязательно оптимизируется позже:

      constexpr int func( int i )
{
    return i+2;
}

int main()
{
     constexpr int i1 = func(8);
     auto i2 = i1;
     i2 = 9;
}

Хотя вам может не понравиться этот метод, я думаю, что он работает без каких-либо проблем....

Вы также можете использовать что-то вроде этого (на основе идеи StoryTeller ):

      template<typename T> constexpr std::remove_const_t<T> const_eval(T&& res) { return res; }

которые также поддерживают возврат ссылок из метода.

Мне просто интересно, почему constinit ограничен статическими переменными. Для меня [так в оригинале] это не имеет особого смысла.

Постоянная инициализация и динамическая инициализация — это концепции, применимые только к объектам со статической продолжительностью хранения. Спецификатор просто означает, что мы ожидаем, что переменная подвергнется первому, а не второму. Это не инструмент оптимизации, а способ систематизировать поведение нашего кода. Без него динамическая инициализация может происходить незаметно, и, как может сказать вам любой программист на C++, побывавший в этом блоке, это также означает фиаско статического порядка инициализации.

С , мы либо получаем ожидаемое поведение, либо диагностику. Это не относится к автоматическим переменным, потому что они не страдают от той же проблемы, что и статические переменные.

Но если вы хотите убедиться инициализируется чем-то, что может быть оценено константой, тогда это не так сложно выполнить.

      template<auto result> consteval auto const_eval() { return result; }

int main()
{
     int i = const_eval<func(8)>();
     i = 9;
}

Если не может быть оценена константой, это серьезная ошибка. Будет ли компилятор оптимизировать его для загрузки постоянного значения? Скорее всего. Компиляторы хороши в таких вещах.

Другие вопросы по тегам