gpt4 book ai didi

c++ - 投入 constexpr 函数 : do we need wrapping condition?

转载 作者:行者123 更新时间:2023-12-01 14:48:03 25 4
gpt4 key购买 nike

基本思路是这样的:我有一些 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 相关的章节,但我对此表示怀疑。

最佳答案

所以:

  • 根据constexpr函数的编译是一个“懒惰”的过程,那么constexpr函数是否符合要求的检查只在表达式替换过程中编译器仍然进入的范围内进行。
  • 一个函数分别是一个作用域——constexpr 的所有规则必须在函数的第一级作用域的整个主体中遵守。
  • 并且由于表达式“throw”不是常量表达式(正如 gcc-10 编译器已经告诉我们的那样),因此未观察到正确性。

  • 在这个意义上,clang 编译器不像 gcc 那样严格。因此,在这场战斗中,在我看来,gcc 获胜。他更致力于标准。
    另一方面,如果这是一个“懒惰”的过程,那么为什么不应该懒惰到最后。好吧,你找到了最终的返回——那么为什么要进一步检查正确性呢?
    从这个意义上说,clang 得到了一个点。
    最后 - C++17 Standard 说什么?
    10.1.5 constexpr 说明符 [dcl.constexpr]
  • "...如果不存在参数值,使得函数或构造函数的调用可以是核心常量表达式 (8.20) 的评估子表达式,...,程序格式错误,无需诊断。

  • 接下来我们看看什么是“核心常量表达式”:
    8.20 常量表达式 [expr.const]
  • 一个表达式是一个评估,遵循抽象机(4.6)的规则,将评估以下表达式之一:

  • 2.22 - throw 表达式 (8.17)
    并注意“不需要诊断”并且编译器不需要提供失败原因的详细解释。

    关于c++ - 投入 constexpr 函数 : do we need wrapping condition?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61420045/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com