Ch7.2: constexpr Object Generation
Overview
A constexpr function can build objects at compile time. In this
chapter, we generate a lookup table of powers of ten using a loop inside a
constexpr function, return the table, and force the compiler to
compute it during compilation.
This technique is useful for precomputed tables such as powers of ten, digit conversion tables, and other fixed data that should not be computed at runtime.
1. Determining how many powers of ten fit
We use std::uint_least64_t to avoid overflow. The number of
safe powers of ten is given by:
constexpr std::size_t pow10_count =
::std::numeric_limits<::std::uint_least64_t>::digits10 + 1;
For 64‑bit integers, this is typically 19 (10⁰ through 10¹⁸).
2. Generating the table with a constexpr function
A constexpr function may contain loops. We use this to fill a
::fast_io::array with powers of ten. The return type is
auto, so the compiler deduces the array type.
constexpr auto make_pow10()
{
::fast_io::array<::std::uint_least64_t, pow10_count> arr{};
::std::uint_least64_t value{1};
for(std::size_t i{}; i != pow10_count; ++i)
{
arr[i] = value;
value *= 10;
}
return arr;
}
This function builds the entire table at compile time.
3. Forcing compile‑time evaluation
To force the compiler to compute the table during compilation, define an
inline constexpr global variable:
inline constexpr auto pow10_table = make_pow10();
A constexpr variable forces its initializer to be evaluated at
compile time. If the initializer calls a constexpr function,
the compiler must execute that function during compilation.
If the computation cannot be completed at compile time, the compilation fails. This happens when:
- the function being called is not
constexpr - the function performs an operation not allowed in constant expressions
- the function triggers undefined behavior
Because the variable is inline, it can be placed in a header
without causing duplicate symbol errors.
4. Using the table in main()
int main()
{
using namespace ::fast_io::iomnp;
println(pow10_table[0]); // 1
println(pow10_table[1]); // 10
println(pow10_table[5]); // 100000
println(pow10_table[18]); // 10^18 (on 64-bit)
}
All values are precomputed and stored directly in the program image.
Key takeaways
digits10tells us how many powers of ten fit in the type.- A
constexprfunction can generate arrays using loops. - Returning
autolets the compiler deduce the array type. inline constexprvariables force compile‑time evaluation.- Compilation fails if the computation cannot be done at compile time.
- The resulting table is embedded directly in the program image.