是否允许对封闭范围的 "capture" 变量使用 requires 表达式?
Are requires expressions allowed to "capture" variables of the enclosing scope?
在下面的示例中,函数参数用于通过 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 是否接受它?
是的,requires-expression 可以使用范围内的任何内容。毕竟,它只需要它命名的任何内容的 type,nested-requirement 或其他常量表达式除外。周围的声明和它自己的(正式)参数一样都是如此。
C++20 在 [expr.prim.req]/5 中明确提到了这一点:
The requirement-body contains a sequence of requirements. These
requirements may refer to local parameters, template parameters, and any other declarations visible from the enclosing context.
然而,这只是一般规则的重述,因此已被删除。
在下面的示例中,函数参数用于通过 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 是否接受它?
是的,requires-expression 可以使用范围内的任何内容。毕竟,它只需要它命名的任何内容的 type,nested-requirement 或其他常量表达式除外。周围的声明和它自己的(正式)参数一样都是如此。
C++20 在 [expr.prim.req]/5 中明确提到了这一点:
The requirement-body contains a sequence of requirements. These requirements may refer to local parameters, template parameters, and any other declarations visible from the enclosing context.
然而,这只是一般规则的重述,因此已被删除。