C++ 如果我使用const引用作为constexpr函数而不是类型的参数,有什么区别?

C++ 如果我使用const引用作为constexpr函数而不是类型的参数,有什么区别?,c++,constexpr,C++,Constexpr,我有以下代码: inline constexpr int fibo(unsigned const &i) { if (i == 0) return 0; if (i == 1 || i == 2) return 1; return fibo(i - 1) + fibo(i - 2); } 我收到以下错误消息: “constexpr”计算操作计数超过了33554432的限制(使用-fconstexpr ops limit=增加限制) 错误:静态断言static

我有以下代码:

inline constexpr int fibo(unsigned const &i) {
    if (i == 0) return 0;
    if (i == 1 || i == 2) return 1;

    return fibo(i - 1) + fibo(i - 2);
}
我收到以下错误消息:

  • “constexpr”计算操作计数超过了33554432的限制(使用-fconstexpr ops limit=增加限制)
  • 错误:静态断言static_assert的非常量条件(1'836'311'903==fibo(46),“fibo(46)”
但如果我使用以下定义:

inline constexpr int fibo(unsigned i);
我没有收到错误消息


如果我使用常量&?

只是一个猜测,而不知道这是否是真正的原因,那么这意味着什么,但可能是没有
常量&
尾部调用优化是可能的,而使用
常量&
则不可能。如前所述,iirc,此例程无法进行尾部调用优化。因为它需要在框架中维护一个状态来对递归结果执行加法操作。似乎只有gcc有区别。在这两种情况下,clang都无法编译。请注意,编译器不必进行记忆。使用值进行记忆比较简单,而使用(const)引用时,值和地址可能很重要,而使用临时
i-1
i-2
,您永远不会有相同的地址。(的确,
i
没有使用ODR,s值应该足够了)。只是猜测一下,不知道这是否是真正的原因,但可能是没有
const&
尾调用优化是可能的,而有了
const&
就不可能了。如文所述,iirc,此例程无法进行尾调用优化。因为它需要在框架中维护一个状态来对递归结果执行加法操作。似乎只有gcc有区别。在这两种情况下,clang都无法编译。请注意,编译器不必进行记忆。使用值进行记忆比较简单,而使用(const)引用时,值和地址可能很重要,而使用临时
i-1
i-2
,您永远不会有相同的地址。(的确,
i
未使用ODR,s值应足够)。