递归 lambda 中斐波那契数列的编译时计算不准确

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

下面是一个递归 lambda 表达式,可以在运行时和持续求值期间计算 斐波那契序列 的值:

auto fib = [](this auto && f, auto && p) {
    if ( p < 3 ) return 1;
    decltype(+p) v{};
    v = p - 2;
    return f(v+1) + f(v);
};

// ok everywhere
static_assert( fib(1) == 1 );
static_assert( fib(2) == 1 );
static_assert( fib(3) == 2 );
static_assert( fib(4) == 3 );
static_assert( fib(5) == 5 );
static_assert( fib(6) == 8 );
static_assert( fib(7) == 13 );
static_assert( 20 <= fib(8) && fib(8) <= 21 );
// fails in MSVC
static_assert( fib(8) == 21 );

据我所知,它在 GCC 和 Clang 中运行良好,但在 Visual Studio 中仅适用于前 7 个元素,并且

fib(8)
计算不准确,导致静态断言失败。在线演示:https://gcc.godbolt.org/z/dMM6f16do

如果程序是正确的,为什么它对于较小的数字表现良好,而对于较大的数字则不起作用(例如整数溢出、太多的递归调用)?

c++ lambda constexpr c++23 explicit-object-parameter
1个回答
0
投票

这绝对是一个 msvc bug。请注意,当我们编写以下内容时,msvc 会打印

21

int main()
{
    std::cout << fib(8) << "\n"; //msvc prints 21
    constexpr int i = fib(8);
    std::cout << i;              //msvc prints 20
}

演示

© www.soinside.com 2019 - 2024. All rights reserved.