C++20coreadvanced
Stateless Lambda Call Operator as consteval (C++20 Addition)
C++20 · The Big Four · Compiler flag: -std=c++20
Explanation
Stateless lambdas can have `consteval` call operators for compile-time execution.
Real-World Scenario
Generate compile-time constants in a configuration system.
Quick Snippet
snippet.cpp
auto lambda = []() consteval { return 42; };Full Example
consteval_lambda.cpp
// CodeNebula - C++20 Example: Consteval Lambdas
// Compile: g++ -std=c++20 -Wall -Wextra -o example consteval_lambda.cpp
// Demonstrates consteval lambdas that are guaranteed to execute at compile
// time. Unlike constexpr lambdas, consteval lambdas cannot be called at
// runtime.
#include <iostream>
#include <array>
// ------------------------------------------------------------------
// 1. Basic consteval lambda
// ------------------------------------------------------------------
consteval auto square(int x) {
return x * x;
}
// ------------------------------------------------------------------
// 2. consteval function using lambda internally
// ------------------------------------------------------------------
consteval int sum_of_squares(int n) {
auto sq = [](int x) consteval { return x * x; };
int total = 0;
for (int i = 1; i <= n; ++i)
total += sq(i);
return total;
}
// ------------------------------------------------------------------
// 3. consteval lambda for compile-time string length
// ------------------------------------------------------------------
consteval int ct_strlen(const char* s) {
int len = 0;
while (s[len] != '\0') ++len;
return len;
}
// ------------------------------------------------------------------
// 4. consteval lambda to generate compile-time lookup table
// ------------------------------------------------------------------
consteval auto make_fibonacci_table() {
std::array<long long, 20> fib{};
fib[0] = 0;
fib[1] = 1;
for (int i = 2; i < 20; ++i)
fib[i] = fib[i - 1] + fib[i - 2];
return fib;
}
// ------------------------------------------------------------------
// 5. consteval lambda for compile-time validation
// ------------------------------------------------------------------
consteval int validated_port(int port) {
if (port < 1 || port > 65535)
throw "Invalid port number"; // Compile-time error if invalid
return port;
}
// ------------------------------------------------------------------
// 6. consteval lambda for factorial
// ------------------------------------------------------------------
consteval long long factorial(int n) {
auto impl = [](auto self, int n) consteval -> long long {
return n <= 1 ? 1 : n * self(self, n - 1);
};
return impl(impl, n);
}
int main()
{
std::cout << "=== Basic consteval ===" << std::endl;
constexpr int sq5 = square(5);
std::cout << " square(5) = " << sq5 << std::endl;
constexpr int sq12 = square(12);
std::cout << " square(12) = " << sq12 << std::endl;
std::cout << "\n=== Sum of Squares (consteval) ===" << std::endl;
constexpr int s3 = sum_of_squares(3); // 1+4+9 = 14
constexpr int s5 = sum_of_squares(5); // 1+4+9+16+25 = 55
std::cout << " sum_of_squares(3) = " << s3 << std::endl;
std::cout << " sum_of_squares(5) = " << s5 << std::endl;
std::cout << "\n=== Compile-Time String Length ===" << std::endl;
constexpr int len1 = ct_strlen("Hello");
constexpr int len2 = ct_strlen("C++20 consteval");
std::cout << " strlen(\"Hello\") = " << len1 << std::endl;
std::cout << " strlen(\"C++20 consteval\") = " << len2 << std::endl;
std::cout << "\n=== Compile-Time Fibonacci Table ===" << std::endl;
constexpr auto fib = make_fibonacci_table();
std::cout << " First 10 Fibonacci numbers:";
for (int i = 0; i < 10; ++i)
std::cout << " " << fib[i];
std::cout << std::endl;
std::cout << " fib[19] = " << fib[19] << std::endl;
std::cout << "\n=== Compile-Time Validation ===" << std::endl;
constexpr int port = validated_port(8080);
std::cout << " Validated port: " << port << std::endl;
constexpr int port2 = validated_port(443);
std::cout << " Validated port: " << port2 << std::endl;
// validated_port(70000); // Would cause compile-time error
std::cout << "\n=== Consteval Factorial ===" << std::endl;
constexpr auto f5 = factorial(5);
constexpr auto f10 = factorial(10);
constexpr auto f15 = factorial(15);
std::cout << " 5! = " << f5 << std::endl;
std::cout << " 10! = " << f10 << std::endl;
std::cout << " 15! = " << f15 << std::endl;
// All values are compile-time constants
static_assert(square(6) == 36);
static_assert(factorial(6) == 720);
std::cout << "\n static_assert checks passed" << std::endl;
return 0;
}
/*
Expected output:
=== Basic consteval ===
square(5) = 25
square(12) = 144
=== Sum of Squares (consteval) ===
sum_of_squares(3) = 14
sum_of_squares(5) = 55
=== Compile-Time String Length ===
strlen("Hello") = 5
strlen("C++20 consteval") = 15
=== Compile-Time Fibonacci Table ===
First 10 Fibonacci numbers: 0 1 1 2 3 5 8 13 21 34
fib[19] = 4181
=== Compile-Time Validation ===
Validated port: 8080
Validated port: 443
=== Consteval Factorial ===
5! = 120
10! = 3628800
15! = 1307674368000
static_assert checks passed
*/
Run command
g++ -std=c++20 -Wall -Wextra -o example consteval_lambda.cpp