为什么 require 子句中的否定表达式需要括号?

Már*_*ldi 2 c++ templates c++-concepts c++20

以下代码是 -clause 的用法示例requires

#include <type_traits>

template <typename T>
  requires std::is_integral_v<T>
void take_integral(T value);
Run Code Online (Sandbox Code Playgroud)

它接受一个计算结果为bool值的表达式(std::is_integral_v<T>在本例中),并按预期工作。但是,当使用运算符对此类表达式求反时!,会导致编译错误:

#include <type_traits>

template <typename T>
  requires !std::is_integral_v<T>
void take_integral(T value);
Run Code Online (Sandbox Code Playgroud)

来自 GCC 的诊断:

<source>:4:12: error: expression must be enclosed in parentheses
    4 |   requires !std::is_integral_v<T>
      |            ^~~~~~~~~~~~~~~~~~~~~~
      |            (                     )
Compiler returned: 1
Run Code Online (Sandbox Code Playgroud)

来自 Clang 的诊断:

<source>:4:12: error: parentheses are required around this expression in a requires clause
  requires !std::is_integral_v<T>
           ^~~~~~~~~~~~~~~~~~~~~~
           (                     )
1 error generated.
Compiler returned: 1
Run Code Online (Sandbox Code Playgroud)

这里为什么需要括号?

Már*_*ldi 5

括号是必需的,因为它们可以避免语言解析的歧义。

\n\n

并非所有表达式都可以出现在requires- 子句中。事实上,该标准给出了一个示例,说明如果允许所有表达式,将如何出现解析歧义:

\n\n
\n

[温度预]/9

\n\n

[...] require-clause中的表达式使用受限语法来避免歧义。\n 括号可用于指定require-clause中的任意表达式。[ 例子:

\n\n
template<int N> requires N == sizeof new unsigned short\nint f();            // error: parentheses required around == expression\n
Run Code Online (Sandbox Code Playgroud)\n\n

\xe2\x80\x94 结束示例]

\n
\n\n

在标准给出的上述示例中,编译器不可能知道该sizeof部分是否应该被解析为sizeof表达式的anew unsigned shortnew unsigned short int。将其放在括号中,例如requires (N == sizeof new unsigned short),可以解决问题。

\n


归档时间:

查看次数:

825 次

最近记录:

5 年,8 月 前