पाठ 18 / 25
auto, decltype, constexpr and Compile-Time Programming
Use type deduction and compile-time evaluation effectively.
Letting the compiler do the work
Modern C++ moves more work to the compiler. auto deduces variable types and, for functions, return types. decltype(expr) yields the type of an expression, useful in generic code. constexpr functions can be evaluated at compile time when their arguments are constants, and since C++20 they can use loops, local variables, std::vector and std::string inside the evaluation. consteval (C++20) functions must run at compile time, and constinit guarantees a variable is initialised at compile time. static_assert checks conditions during compilation. if constexpr discards branches that do not apply to the instantiated type. Type traits in <type_traits> (std::is_integral_v<T>, std::remove_cvref_t<T>) inspect and transform types. Together these enable lookup tables computed at build time, configuration checked at compile time and generic code without run-time overhead. Use them when they simplify code or catch errors early, not merely to be clever.
Compile-time computation and checks
The table is computed by the compiler; static_assert verifies it.
#include <array>
#include <cstddef>
#include <string>
#include <type_traits>
constexpr std::array<unsigned long long, 21> make_factorials() {
std::array<unsigned long long, 21> f{};
f[0] = 1;
for (std::size_t i = 1; i < f.size(); ++i) f[i] = f[i - 1] * i; // loops allowed in constexpr
return f;
}
constexpr auto factorials = make_factorials(); // computed at compile time
static_assert(factorials[5] == 120);
static_assert(factorials[20] == 2'432'902'008'176'640'000ULL);
consteval int kib(int n) { return n * 1024; } // must be compile-time
constexpr int buffer_size = kib(64);
template <typename T>
std::string describe(const T& value) {
if constexpr (std::is_integral_v<T>) return "integer " + std::to_string(value);
else if constexpr (std::is_floating_point_v<T>) return "real " + std::to_string(value);
else return "something else";
}constexpr is permission, not a promise
A constexpr function can still run at run time when given run-time values. If evaluation must happen at compile time, use the result in a constexpr variable, a static_assert, or mark the function consteval.
त्वरित जाँच: What does consteval guarantee about a function?
- Every call is evaluated at compile time
- It runs only at run time
- It is inlined
- It cannot use loops
Answer
Every call is evaluated at compile time — consteval functions are immediate functions: each call must produce a compile-time constant.