tg-me.com/cpluspluc/1026
Last Update:
❓ Что выведет этот код? (C++23)
import std;
constexpr auto make_checker() {
return [](int x) consteval {
return x % 3 == 0 || x % 5 == 0;
};
}
int main() {
auto checker = make_checker();
std::vector numbers{1, 3, 5, 9, 10, 14, 15};
auto filtered = numbers | std::views::filter([&](int x) {
if (std::is_constant_evaluated()) {
std::print("constexpr\n");
}
return checker(x);
});
std::print("Filtered numbers: ");
for (int x : filtered) {
std::print("{} ", x);
}
std::println("");
}
🧠 Подсказка:
std::is_constant_evaluated() — интересный механизм проверки, вызывается ли код во время компиляции.
Как отреагирует компилятор на попытку вызвать consteval функцию в runtime?
📌 Ответ
🔍 Напоминаем ключевой фрагмент кода:
```cpp
constexpr auto make_checker() {
return [](int x) consteval {
return x % 3 == 0 || x % 5 == 0;
};
} ```
- Здесь создаётся лямбда-функция, помеченная как consteval.
- Ключевое слово consteval означает: функция обязана быть вызвана во время компиляции.
🧨 Где ошибка?
return checker(x); // ← ошибка тут
});
checker — это consteval-лямбда.
Но ты вызываешь её внутри лямбды, которая будет работать во время выполнения программы — т.е. в runtime.
Это нарушение правила consteval → нельзя вызывать такие функции в runtime-коде.
❌ Что скажет компилятор?
Компилятор выдаст ошибку компиляции, такую или похожую:
error: call to consteval function '<lambda>(int)' is not a constant expression
📘 Объяснение
consteval ≠ constexpr
constexpr — это могут быть вызваны в runtime, если нужно.
consteval — это всегда и только compile-time.
Когда ты вызываешь checker(x) в main(), ты нарушаешь это правило.
✅ Как можно исправить?
Если ты заменишь consteval на constexpr, код скомпилируется и выполнится:
constexpr auto make_checker() {
return [](int x) constexpr {
return x % 3 == 0 || x % 5 == 0;
};
}
И тогда результат будет:
Filtered numbers: 3 5 9 10 15
Потому что:
- 3 делится на 3
- 5 делится на 5
- 9 делится на 3
- 10 делится на 5
- 15 делится на 3 и 5
BY C++ Academy
Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283
Share with your friend now:
tg-me.com/cpluspluc/1026