【问题标题】:Requires clause with pure abstract class type parameter?需要带有纯抽象类类型参数的子句?
【发布时间】:2021-06-11 11:40:33
【问题描述】:

考虑以下简单的concept

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

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

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

static_assert(C<B>);

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

标准是怎么说的?

【问题讨论】:

    标签: c++ language-lawyer abstract-class c++20 c++-concepts


    【解决方案1】:

    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
    

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

    【讨论】:

    • 这种明显无用的放松的原因是函数可以用不完整类的参数类型声明;后续将类定义为抽象类以追溯使函数声明无效是有问题的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多