Date: Tue, 29 Apr 2025 12:02:33 +0800
A supplement:
uint64_t myLog(uint64_t a, uint64_t b) {
if consteval (b) { // first judge whether b is constexpr
if (isPowerOfTwo(b)) { // then judge whether b is power of two
// Optimized implementation for b being compile-time known and
a power of 2
return ...;
} else {
// Other implementation for known b
}
}
// Generic implementation
}
int main()
{
uint64_t a, b;
std::cin >> a >> b;
std::cout << myLog(a, 2) << std::endl; // the parameter b (=2) is
obviously constexpr, and will use the optimized implementation of myLog for
known b=2, the same effect as myLog2(a) (without explicit parameter b=2)
std::cout << myLog(a, 3) << std::endl; // the parameter b (=3) is
obviously constexpr, and will use the other implementation of myLog for
known b=3, the same effect as myLog3(a) (without explicit parameter b=3)
std::cout << myLog(a, b) << std::endl; // b is not constexpr, and will
use the generic implementation
return 0;
}
None <a1343922569_at_[hidden]> 于2025年4月28日周一 19:46写道:
> 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
>
uint64_t myLog(uint64_t a, uint64_t b) {
if consteval (b) { // first judge whether b is constexpr
if (isPowerOfTwo(b)) { // then judge whether b is power of two
// Optimized implementation for b being compile-time known and
a power of 2
return ...;
} else {
// Other implementation for known b
}
}
// Generic implementation
}
int main()
{
uint64_t a, b;
std::cin >> a >> b;
std::cout << myLog(a, 2) << std::endl; // the parameter b (=2) is
obviously constexpr, and will use the optimized implementation of myLog for
known b=2, the same effect as myLog2(a) (without explicit parameter b=2)
std::cout << myLog(a, 3) << std::endl; // the parameter b (=3) is
obviously constexpr, and will use the other implementation of myLog for
known b=3, the same effect as myLog3(a) (without explicit parameter b=3)
std::cout << myLog(a, b) << std::endl; // b is not constexpr, and will
use the generic implementation
return 0;
}
None <a1343922569_at_[hidden]> 于2025年4月28日周一 19:46写道:
> 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
>
Received on 2025-04-29 04:02:47