下标运算符与参数包展开的语法问题及MSVC兼容性问询
关于MSVC对参数包展开下标访问约束的兼容性问题
在使用参数包展开实现下标访问的语法检查时,预期以下代码可正常运行无错误,但MSVC既拒绝requires子句中的约束语法,也不通过最后一条断言。
代码示例
template<typename T, typename... Ts> concept c = requires(T t, Ts... ts) { { t[ts...] } noexcept; // clang ok, gcc ok, msvc nope }; static_assert(not c<int[]>); // all ok static_assert(not c<int[], int, int>); // all ok static_assert(c<int[], int>); // clang ok, gcc ok, msvc nope
MSVC错误信息
<source>(3): error C2760: syntax error: 'noexcept' was unexpected here; expected ';' <source>(3): error C2760: syntax error: ']' was unexpected here; expected '}' <source>(8): error C2607: static assertion failed <source>(8): note: the concept 'c<int[],int>' evaluated to false
问题解答
这属于MSVC的编译器Bug,代码完全符合C++23标准的规定,具体依据如下:
下标表达式的参数包展开规则:C++23标准在
[expr.sub](下标表达式)章节中明确,下标运算符[]的操作数允许参数包展开,只要展开后的结果是单个表达式(匹配数组下标所需的单个索引参数要求)。对于c<int[], int>,参数包Ts...展开后为单个int,此时t[ts...]等价于合法的数组下标表达式t[int]。复合要求的noexcept检查:C++23标准在
[expr.prim.req.compound](复合要求)章节中规定,复合要求的语法允许在{ 表达式 }后添加noexcept,用于验证该表达式是否是noexcept的。代码中的{ t[ts...] } noexcept完全符合这一语法规则。
MSVC出现的语法错误和概念评估错误,均是对C++23上述标准特性支持不完整导致的问题。
内容的提问来源于stack exchange,提问作者303
相关产品推荐
相关产品推荐

