需要带有纯抽象 class 类型参数的子句?

Requires clause with pure abstract class type parameter?

考虑以下简单的 concept

template <typename T>
concept C = requires(T a) { a.f(); };

如果我们采用 抽象 class 类型作为 requires 表达式 的参数会发生什么?

struct B { virtual void f() = 0; };

static_assert(C<B>);

gcc-trunk 和 msvc-trunk 通过 断言,但是,clang-trunk、gcc-10.2 和 msvc v19.24 reject 断言。

标准怎么说?

GCC-trunk 和 MSVC-trunk 是正确的。由于 P0929,C++17 和 C++20 之间抽象类型的使用限制已 更改。因此,现在甚至允许使用抽象参数类型的普通函数声明:

void foo(B b);  // ill-formed in C++17, well-formed in C++20
void foo(B b) { /* ... */ }  // still ill-formed in C++20

措辞“抽象 class 不得用作参数类型...”(C++17 [class.abstract]/3) 已被删除。在 C++20 中,仅当函数被调用 ([expr.call]/7) 或定义 ([dcl.fct.def.general]/2 时,函数才具有抽象参数类型是格式错误的).此外,在 requires-parameter-list 中找到的 parameter-declaration 不是定义,就像 parameter-在函数的非定义声明中发现的声明 不是定义 ([basic.def]/2.8).