Я думаю, что этот код в порядке.
Существенным аспектом consteval
является [expr.const] / 12 :
Выражение илипреобразование происходит в непосредственном контексте функции , если оно потенциально оценивается и его внутренняя неблокированная область является областью параметра функции непосредственной функции. Выражение или преобразование - это немедленный вызов , если это явный или неявный вызов непосредственной функции и не находится в непосредственном контексте функции. Немедленный вызов должен быть постоянным выражением.
In
void test() {
A a;
a = f(); // <-- here
}
f()
- это немедленный вызов (это явный вызов непосредственной функции, которая не находится в непосредственном контексте функции). Таким образом, требование заключается в том, что f()
должно быть константным выражением.
Примечание: просто f()
, а не a = f();
, здесь не требуется, чтобы оператор присваивания был константным выражением.
Все, что вызывает f()
, прекрасно. Все специальные функции-члены A
доступны в течение постоянного времени оценки. Результат f()
является допустимым результатом константного выражения ( [expr.const] / 10 ) аналогичным образом, поскольку оно также не вызывает каких-либо ограничений там (A
не имеет указателя или ссылкичлены, так что, как правило, ни один из них не ссылается на объекты без статической длительности хранения).
В конечном счете, вопрос о постоянной оценке сводится к тому, чтобы пройти через весь список ограничений и посмотреть, не сломалось ли что-нибудь. Я не думаю, что мы нарушаем какое-либо из правил, поэтому это должно быть хорошо.