首页 > 解决方案 > 不完整类上下文中的 C++ 概念检查

问题描述

请考虑一个 C++20 概念程序:

struct A {};

template<typename T>
concept DerivedOnceFromA = requires(T t) { { static_cast<const A&>(t) }; };

template<DerivedOnceFromA T>
struct B {};

struct C : A
{
    B<C> foo();
};

这里的概念DerivedOnceFromA检查T可以静态转换为A. B是遵循这个概念的模板结构。并且 structC派生自A(因此概念得到满足)并定义了一个返回的函数B<C>

此代码被 GCC 和 MSVC 接受,但被 Clang 拒绝并出现以下错误:

constraints not satisfied for class template 'B' [with T = C]

演示:https ://gcc.godbolt.org/z/7Tc7xdbeq

在类体内使用类作为概念模板参数是否合法(那么什么编译器是正确的)?

标签: c++c++20c++-concepts

解决方案


合法的?是的,在范围内。但是您无法收集到任何有用的信息。

[class.mem.general]

6一个类的完整类上下文是

  • 函数体([dcl.fct.def.general]),
  • 默认参数,
  • noexcept 说明符([except.spec]),或
  • 类的成员规范中的默认成员初始值设定项。

7类在类说明符结束时被视为完全定义的对象类型([basic.types])(或完整类型)}。该类在其完整类上下文中被认为是完整的;否则,它在其自己的类成员规范内被视为不完整。

所以你使用它的时候它仍然被认为是不完整的,只是你最多转发声明的一种类型。因此,无论启用强制转换的机制(继承或用户定义的转换运算符)如何,您都无法知道它是否可以转换为其他引用。即使A借助诸如std::derived_from. 不完整类型的可观察属性非常有限。


推荐阅读