c++ constexpr pow()函数编译器失败

xsuvu9jc  于 2023-03-14  发布在  其他
关注(0)|答案(1)|浏览(163)

如果我试着这样做:

template <auto X, auto E>
constexpr decltype(X) const_pow() noexcept
{
  return !E ? 1 : 1 == E ? X : (E % 2 ? X : 1) * const_pow<X * X, E / 2>();
}

我得到一个error

prog.cc: In instantiation of 'constexpr decltype (X) const_pow() [with auto X = 100000000; auto E = 0; decltype (X) = int]':
prog.cc:6:73:   recursively required from 'constexpr decltype (X) const_pow() [with auto X = 100; auto E = 1; decltype (X) = int]'
prog.cc:6:73:   required from 'constexpr decltype (X) const_pow() [with auto X = 10; auto E = 3; decltype (X) = int]'
prog.cc:11:32:   required from here
prog.cc:6:62: warning: integer overflow in expression of type 'int' results in '1874919424' [-Woverflow]
    6 |   return !E ? 1 : 1 == E ? X : (E % 2 ? X : 1) * const_pow<X * X, E / 2>();
      |                                                            ~~^~~
prog.cc:6:73: error: no matching function for call to 'const_pow<(100000000 * 100000000), (0 / 2)>()'

解决方法很简单(例如requiresif constexpr),但是为什么编译器不自己结束递归呢?

tzdcorbm

tzdcorbm1#

[温度 Jmeter ]/5:
除非函数模板专门化是声明的专门化,否则当专门化在需要函数定义存在的上下文中被引用时,或者如果定义的存在影响程序的语义时,函数模板专门化被隐式示例化。
[基本定义odr]/11:
每个程序应包含至少一个定义的每个函数或变量是odr使用在该程序以外的一个废弃的语句;不需要诊断。
[基本定义odr]/8:
如果一个函数是由一个可能求值的表达式或转换命名的,则该函数是odr-used函数。
[基本.定义.odr]/4.1:
如果函数是重载解析中重载集的选定成员,则该函数由表达式或转换命名,重载解析是作为形成该表达式或转换的一部分而执行的[...]
条件表达式odr-中的调用使用const_pow<...>,而不管是否执行分支,从而导致其示例化。

相关问题