C++ Logo

std-proposals

Advanced search

[std-proposals] Idea and proposal: Concise mechanism for detecting specific constexpr arguments within functions

From: None <a1343922569_at_[hidden]>
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

Received on 2025-04-28 11:46:43