constexpr 一般混乱

问题描述 投票:0回答:1

我昨天发了一个帖子,但我认为它不清楚,得到的回复根本没有解决我的困惑。所以,我会尽量让这个例子更简单。

为什么允许这样做:

constexpr int incr(int k1)
{
    return k1 + 5;
}

constexpr int foo(int k)  // runs in compile time
{
    return incr(k);
}

int main() {
    constexpr int x = 5;
    constexpr int y = foo(4);
}

...但是这个非常相似的功能不是吗?

constexpr int incr(int k1)
{
    return k1 + 5;
}

constexpr int foo(int k)  // runs in compile time
{
    constexpr int x = incr(k); // k: not a constant expression
    return x;
}

int main() {
    constexpr int x = 5;
    constexpr int y = foo(4);
}

在不断评估的情况下,这两个函数究竟有何不同?对我来说,它们看起来几乎完全一样,除了一个立即返回而另一个首先计算值并将其分配给 constexpr 变量。

如果可以,也请参考标准,以便我进一步阅读!

c++ language-lawyer constexpr compile-time-constant constant-expression
1个回答
0
投票

constexpr
修饰符,当应用于函数时,仅给出函数在编译时运行的 possibility (此外,在 C++23 草案中,
constexpr
函数不再受到以前的限制,因此你最好把它当作合同来读,作者给出的支持
constexpr
语义的“承诺”)。修饰符并没有取消这个事实,即相同的函数也可能在运行时运行:

int main() {
    constexpr int compileVar = foo(2);
    int param = 4;
    int runtimeVar = foo(param);
}

因此不能保证传递给

constexpr
函数的参数在编译时被评估。

另一方面,

constexpr
修饰符,当应用于 variables 时,only 在编译时被评估,并且编译器合理地阻止您使用函数的(可能)运行时参数来评估编译-时间变量。

在不断评估的情况下,这两个函数究竟有何不同?

我认为这里的主要误解是,如果函数在编译时求值,则

constexpr
函数的所有部分都在编译时求值,无论内部变量是否具有
constexpr
修饰符。所以这个函数的正确等价物:

constexpr int foo(int k)
{
    return incr(k);
}

会是:

constexpr int foo(int k)
{
    int x = incr(k);
    return x;
}
© www.soinside.com 2019 - 2024. All rights reserved.