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

标签 c++ templates c++20 c++-concepts

以下代码是 requires 的使用示例- 子句:

#include <type_traits>

template <typename T>
  requires std::is_integral_v<T>
void take_integral(T value);

它接受一个计算结果为 bool 的表达式值(在本例中为 std::is_integral_v<T>),并按预期工作。 然而,当这样的表达式被 ! 否定时运算符,它会导致编译错误:

#include <type_traits>

template <typename T>
  requires !std::is_integral_v<T>
void take_integral(T value);

GCC 诊断:

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

从 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

为什么这里需要括号?

最佳答案

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

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

[temp.pre]/9

[...] The expression in a requires-clause uses a restricted grammar to avoid ambiguities. Parentheses can be used to specify arbitrary expressions in a requires-clause. [ Example:

template<int N> requires N == sizeof new unsigned short
int f();            // error: parentheses required around == expression

— end example ]

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

关于c++ - 为什么 require 子句中的否定表达式需要括号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60911124/

相关文章:

c++ - C++概念和 `std::is_same`的模板参数推导问题

c++ - 事件回调守护进程

c++ - std::invocable 和 std::regular_invocable 概念之间有什么区别?

c++ - 为什么SFML Shader会导致segmentation fault?

c++ - 如何重新定义内置键盘快捷键的行为?

java - 具有客户端模板的受限页面

C++概念和转换问题

c++ - 使用模板参数列表调用 lambda,不提供参数

c++ - msvc9、iostream 和 2g/4g plus 文件

c++ - 检查 void* to Object with static_cast 是否成功