确定 `constexpr` 的执行 - 在编译期间还是在运行时?

Determine `constexpr` execution - during compilation or at runtime?

有没有办法在编译阶段和运行时实现 constexpr 函数的不同行为?

考虑以下示例(使用 D: static if 中的理论特征):

constexpr int pow( int base , int exp ) noexcept
{
    static if( std::evaluated_during_translation() ) {
        auto result = 1;
        for( int i = 0 ; i < exp ; i++ )
            result *= base;
        return result;
    } else { // std::evaluated_during_runtime()
        return std::pow( base , exp );
    }
}

如果不是,有没有办法限制 constexpr 仅在编译时?

不,没有这样的方法。

对不起。

N3583 is a paper 提出更改以实现您的要求。

在 C++20 之前,这是不可能的。 C++20 然后添加了 std::is_constant_evaluated 这正是这个用例:

constexpr int pow(int base, int exp) noexcept
{
    if (std::is_constant_evaluated())
    {
        auto result = 1;

        for (int i = 0; i < exp; i++)
            result *= base;

        return result;
    } 
    else
    {
        return std::pow(base, exp);
    }
}

请注意,if 语句本身是 而不是 constexpr。如果是,整个 else 分支将从函数中删除,它总是 运行 if 分支,无论是在编译时还是 运行 时。使用普通的 if 语句,您基本上可以获得两个函数。一个在编译时 运行s:

constexpr int pow(int base, int exp) noexcept
{
    auto result = 1;

    for (int i = 0; i < exp; i++)
        result *= base;

    return result;
}

还有一个在 运行 时间编译了 运行 秒:

constexpr int pow(int base, int exp) noexcept
{
    return std::pow(base, exp);
}

编译器可以安全地删除 if 分支,因为它可以证明它在 运行 时间不可访问。很整洁。