【问题标题】:Are requires expressions allowed to "capture" variables of the enclosing scope?requires 表达式是否允许“捕获”封闭范围的变量?
【发布时间】:2019-11-05 09:05:57
【问题描述】:

在以下示例中,函数参数用于使用 requires 表达式测试使用它们的表达式是否格式正确。 requires 表达式不带参数;它直接使用函数范围内的变量:

#include <cstddef>
#include <vector>

template<typename T>
void Resize(T &v, std::size_t const n)
{
  if constexpr (requires { v.resize(n); })
    v.resize(n);
}

template<typename T>
void Eziser(T &v, std::size_t const n)
{
  if constexpr (requires { v.eziser(n); })
    v.eziser(n);
}

int main()
{
  std::vector<int> v;

  Resize(v, 10u);
  Eziser(v, 10u);
}

上面的代码使用 Clang 概念分支编译。但是,GCC10 只接受对Resize 的调用。 GCC9 ICE。 Clang 是否正确地接受了它?

【问题讨论】:

  • ICE 总是编译器问题。
  • 我想说,如果不允许捕获局部变量,它应该拒绝代码(因此ResizeEziser 都应该被拒绝)或者两个函数都应该编译。我会说 clang 是对的。
  • @Jarod42 是的。 GCC 行为显然是错误的。我会提交PR。我也认为 Clang 是对的,但我想确认一下。

标签: c++ c++20 c++-concepts


【解决方案1】:

是的,requires-expression 可以使用范围内的任何内容。毕竟,它只需要它命名的任何东西的type,除了在nested-requirement 或其他常量表达式中。周围的声明和它自己的(正式)参数一样都是如此。

C++20 在 [expr.prim.req]/5 中明确提到了这一点:

requirement-body 包含一系列requirements。这些 requirements 可以引用本地参数、模板参数和从封闭上下文可见的任何其他声明。

然而,这只是对一般规则的重述,因此已被删除。

【讨论】:

  • 这一段似乎已从当前草案中全部删除。情况是否有所改变?
  • @metalfox:规则没有改变,但那段是对语法和基本名称查找行为的毫无意义的重述,这就是为什么我没有引用它并且它已经消失了。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多