基本思路是这样的:我有一些 constexpr
功能,我想使用 throw
发出错误信号和延迟编译以避免在正常流程中出现此错误:
template <size_t N>
auto constexpr find_elt(const std::array<int, N>& a, int k) {
for (size_t i = 0; i < N; ++i)
if (k == a[i])
return i;
throw "not found";
}
进而:
constexpr int result = find_elt(arr, 4);
通常,如果数组中存在 4,我会在编译时取回它的索引。
如果没有,我会失败到
throw
表明在编译时查找是错误的,编译器会产生一个相当大的错误。但我注意到奇怪的行为:
Under the latest clang, everything works
Under the latest gcc, everything fails
这个想法合法吗?这段代码对于我想要实现的目标是否正确?哪个编译器在这里告诉我真相?
如果没有,这样做的正确方法是什么?
感谢任何指向 C++ 标准的链接。我通读了与 constexpr 相关的章节,但我对此表示怀疑。
最佳答案
所以:
在这个意义上,clang 编译器不像 gcc 那样严格。因此,在这场战斗中,在我看来,gcc 获胜。他更致力于标准。
另一方面,如果这是一个“懒惰”的过程,那么为什么不应该懒惰到最后。好吧,你找到了最终的返回——那么为什么要进一步检查正确性呢?
从这个意义上说,clang 得到了一个点。
最后 - C++17 Standard 说什么?
10.1.5 constexpr 说明符 [dcl.constexpr]
接下来我们看看什么是“核心常量表达式”:
8.20 常量表达式 [expr.const]
2.22 - throw 表达式 (8.17)
并注意“不需要诊断”并且编译器不需要提供失败原因的详细解释。
关于c++ - 投入 constexpr 函数 : do we need wrapping condition?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61420045/