允许使用闭包来“捕获”外部作用域的变量吗?

11
在下面的示例中,函数参数被用于通过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会出现内部编译错误。Clang在接受它方面是正确的吗?

3
ICE总是编译器问题。 - Jarod42
我认为,如果它不允许捕获局部变量,那么它应该拒绝代码(因此ResizeEziser都应该被拒绝),或者两个函数都应该编译。我认为clang是正确的。 - Jarod42
@Jarod42 是的。GCC的行为明显有缺陷。我会提交一个PR。我也认为Clang是正确的,但我想确认一下。 - metalfox
1个回答

8

是的,一个 要求表达式 可以使用任何在其作用域内的内容。毕竟它只需要引用的任何东西的类型,除了在嵌套要求或其他常量表达式中。这对于周围声明和它自己(形式)参数同样适用。

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

要求体 包含一系列 要求。这些要求可能涉及局部参数、模板参数以及从封闭上下文可见的任何其他声明。

然而,这仅是一般规则的重申,因此已被删除。


这段文字似乎已经从当前草稿中完全删除了。情况是否有所改变? - metalfox
1
@metalfox:规则没有改变,但那段话是语法和基本名称查找行为的无意义重申,这就是为什么我没有引用它并且它已经消失的原因。 - Davis Herring

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接