Date: Mon, 28 Apr 2025 19:46:28 +0800
Hello everyone,
I would like to propose a feature enhancement for future C++ standards that
addresses a current limitation in constexpr-related mechanisms.
*Motivation*
C++20 has introduced std::is_constant_evaluated and consteval function, and
C++23 further provided the "if consteval" expression, enabling developers
to detect within a function whether "the entire function call" is in a
constant evaluation context. However, these mechanisms cannot fulfill the
need to detect whether "specific parameters" are constant expressions.
*Problem Description*
Consider the following function implementing "integer logarithm
calculation" (, avoiding the need to define a separate function for special
cases, and instead handling both general and exceptional cases within a
single function):
uint64_t myLog(uint64_t a, uint64_t b) {
// Calculate floor(log_b(a))
if (isPowerOfTwo(b)) {
// Optimized implementation for b being a power of 2
} else {
// Generic implementation
}
}
When parameter b is known at compile time and is a power of 2, an efficient
bit manipulation implementation can be used; but if b is not a compile-time
constant, the condition check incurs runtime overhead.
This issue can be solved by using a non-type parameter template, but the
function call must be written like "myLog<b>(a);", which looks unnatural
and lacks consistency with "mylog(a, b)".
Existing "if consteval" can only execute a special path when all parameters
are constexpr, but cannot optimize for cases where "only specific
parameters are constexpr".
*Proposed Feature*
I propose introducing a mechanism to detect whether specific parameters are
constexpr. Possible syntax forms include (but are not limited to):
// Possible syntax form 1a
if consteval (parameter_name) {
// For cases where the parameter with specific name is constexpr
} else {
// For cases where the parameter with specific name is not constexpr
}
// Possible syntax form 1b
if constarg (parameter_name) {
// For cases where the parameter with specific name is constexpr
} else {
// For cases where the parameter with specific name is not constexpr
}
// Possible syntax form 2a
if consteval (parameter_index) {
// For cases where the parameter at a specific index location is
constexpr
} else {
// For cases where the parameter at a specific index location is not
constexpr
}
// Possible syntax form 2b
if constarg (parameter_index) {
// For cases where the parameter at a specific index location is
constexpr
} else {
// For cases where the parameter at a specific index location is not
constexpr
}
// Possible syntax form 3
if (std::is_constant_arg<N>()) {
// The Nth parameter is constexpr
}
With this mechanism, the above example could be rewritten as:
uint64_t myLog(uint64_t a, uint64_t b)
{
if consteval (b) {
if (isPowerOfTwo(b)) {
// Optimized implementation for b being compile-time known and
a power of 2
return ...;
}
}
// Generic implementation
}
This would provide possibilities for performance optimization without
affecting interface simplicity.
*Alignment with C++ Evolution*
Since C++11 introduced constexpr, the standard has been continually
expanding and refining constexpr-related features:
C++14 relaxed restrictions on constexpr functions.
C++17 introduced "if constexpr".
C++20 further extended the scope of constexpr and introduced consteval
function and std::is_constant_evaluated.
C++23 introduced "if consteval".
This proposal represents a natural extension of this evolutionary direction.
Best regards,
Jin Haobo
I would like to propose a feature enhancement for future C++ standards that
addresses a current limitation in constexpr-related mechanisms.
*Motivation*
C++20 has introduced std::is_constant_evaluated and consteval function, and
C++23 further provided the "if consteval" expression, enabling developers
to detect within a function whether "the entire function call" is in a
constant evaluation context. However, these mechanisms cannot fulfill the
need to detect whether "specific parameters" are constant expressions.
*Problem Description*
Consider the following function implementing "integer logarithm
calculation" (, avoiding the need to define a separate function for special
cases, and instead handling both general and exceptional cases within a
single function):
uint64_t myLog(uint64_t a, uint64_t b) {
// Calculate floor(log_b(a))
if (isPowerOfTwo(b)) {
// Optimized implementation for b being a power of 2
} else {
// Generic implementation
}
}
When parameter b is known at compile time and is a power of 2, an efficient
bit manipulation implementation can be used; but if b is not a compile-time
constant, the condition check incurs runtime overhead.
This issue can be solved by using a non-type parameter template, but the
function call must be written like "myLog<b>(a);", which looks unnatural
and lacks consistency with "mylog(a, b)".
Existing "if consteval" can only execute a special path when all parameters
are constexpr, but cannot optimize for cases where "only specific
parameters are constexpr".
*Proposed Feature*
I propose introducing a mechanism to detect whether specific parameters are
constexpr. Possible syntax forms include (but are not limited to):
// Possible syntax form 1a
if consteval (parameter_name) {
// For cases where the parameter with specific name is constexpr
} else {
// For cases where the parameter with specific name is not constexpr
}
// Possible syntax form 1b
if constarg (parameter_name) {
// For cases where the parameter with specific name is constexpr
} else {
// For cases where the parameter with specific name is not constexpr
}
// Possible syntax form 2a
if consteval (parameter_index) {
// For cases where the parameter at a specific index location is
constexpr
} else {
// For cases where the parameter at a specific index location is not
constexpr
}
// Possible syntax form 2b
if constarg (parameter_index) {
// For cases where the parameter at a specific index location is
constexpr
} else {
// For cases where the parameter at a specific index location is not
constexpr
}
// Possible syntax form 3
if (std::is_constant_arg<N>()) {
// The Nth parameter is constexpr
}
With this mechanism, the above example could be rewritten as:
uint64_t myLog(uint64_t a, uint64_t b)
{
if consteval (b) {
if (isPowerOfTwo(b)) {
// Optimized implementation for b being compile-time known and
a power of 2
return ...;
}
}
// Generic implementation
}
This would provide possibilities for performance optimization without
affecting interface simplicity.
*Alignment with C++ Evolution*
Since C++11 introduced constexpr, the standard has been continually
expanding and refining constexpr-related features:
C++14 relaxed restrictions on constexpr functions.
C++17 introduced "if constexpr".
C++20 further extended the scope of constexpr and introduced consteval
function and std::is_constant_evaluated.
C++23 introduced "if consteval".
This proposal represents a natural extension of this evolutionary direction.
Best regards,
Jin Haobo
Received on 2025-04-28 11:46:43