在编译期间或运行时确定`constexpr`执行?

时间:2015-02-23 20:54:20

标签: c++ c++14 constexpr

有没有办法在编译阶段和运行时实现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限制为仅编译时间?

2 个答案:

答案 0 :(得分:6)

不,没有这样的方式。

对不起。

N3583 is a paper提议更改以允许您要求的内容。

答案 1 :(得分:3)

在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语句,您基本上可以获得两个功能。在编译时运行的一个:

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臂,因为它可以证明它在运行时不可访问。很整齐。