可以针对不完整的类型检查概念吗

问题描述

我偶然发现了这一点:

#include <type_traits>
#include <concepts>

template<class T>
concept IsFoo = requires(T a)
{
    {a.a} -> std::same_as<int>;
};

#if 1
// Will not compile,because Foo currently has incomplete type
template<IsFoo AFoo>
struct AcceptsFoo
{};
#else
template<class AFoo>
struct AcceptsFoo
{};
#endif

struct Foo
{
    int a;
    int b;

    AcceptsFoo<Foo> obj;
};

https://gcc.godbolt.org/z/j43s4z

其他变体(crtp)https://gcc.godbolt.org/z/GoWfhq

Foo是不完整的,因为它必须实例化AcceptsFoo,但是要这样做,Foo必须完整,否则它无法检查IsFoo。这是GCC中的错误,还是标准这么说?后者会令人遗憾,因为这会阻止将概念与某些众所周知的模式(例如CRTP)一起使用。

我注意到clang确实给出了类似的错误:https://gcc.godbolt.org/z/d5bEez

解决方法

您可以针对不完整的类型检查一个概念-但是,如果该概念检查实际上需要对需要完成的类型做任何事情,那将使概念检查失败。

即使在那儿,您也必须小心,因为允许实现(并且将)缓存概念检查以加快编译速度-因此,如果在C<T>不完整的情况下尝试T,而在{ {1}}完善了,那些应该给出不同的答案,您正在自找麻烦。

T在您检查时还不完整,因此自然没有名称为Foo的成员。这真的可能行不通。

因为这阻止了将概念与一些众所周知的模式(例如CRTP)一起使用。

以这种方式一起使用 ,是的。就像使用CRTP一样,您也无法直接访问传递到基类的template参数之外的任何内容,因此必须始终小心地推迟该类型的任何实例化,直到完成为止。

这最终是相同的原因:

a

不起作用。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...