16 c++ language-lawyer constexpr
我可以constexpr在给出定义之前在 C++ 中声明一个函数吗?
考虑一个例子:
constexpr int foo(int);
constexpr int bar() { return foo(42); }
constexpr int foo(int) { return 1; }
static_assert(bar() == 1);
Run Code Online (Sandbox Code Playgroud)
实际上所有编译器都支持,demo:https : //gcc.godbolt.org/z/o4PThejso
但是如果foo在模板中转换函数:
constexpr int foo(auto);
constexpr int bar() { return foo(42); }
constexpr int foo(auto) { return 1; }
static_assert(bar() == 1);
Run Code Online (Sandbox Code Playgroud)
然后 Clang 拒绝接受它,说https://gcc.godbolt.org/z/EG7cG9KTM:
<source>:5:15: error: static_assert expression is not an integral constant expression
static_assert(bar() == 1);
^~~~~~~~~~
<source>:2:30: note: undefined function 'foo<int>' cannot be used in a constant expression
constexpr int bar() { return foo(42); }
^
<source>:5:15: note: in call to 'bar()'
static_assert(bar() == 1);
Run Code Online (Sandbox Code Playgroud)
它仍然是有效的 C++ 代码还是 Clang 错误?
rus*_*tyx 13
这是核心问题2166。
Section : 7.7 [expr.const] 状态: 起草 提交者: Howard Hinnant 日期: 2015-08-05
根据 7.7 [expr.const] bullet 2.3,表达式是常量表达式,除非(除其他原因外)它会评估
调用未定义的 constexpr 函数或未定义的 constexpr 构造函数;
这并没有解决必须定义 constexpr 函数的点的问题。为了允许相互递归的 constexpr 函数,其意图是必须在最终导致调用的最外层评估之前定义该函数,但这并没有明确说明。
换句话说,标准在这种情况下不清楚,所以每个编译器都可以自由地接受或拒绝它认为合适的代码。
在 Clang 的情况下,auto参数是通过将函数转换为模板来实现的。这使得编译器更难以维护 constexpr 上下文。这并不是说不可能实现(毕竟GCC没问题),只是在2166解决之前不是bug。
同时,您可以通过制作bar()模板或auto从foo().
| 归档时间: |
|
| 查看次数: |
441 次 |
| 最近记录: |