GCC 对 std::invocable 的实现是不正确还是不完整?

互联网 行业动态 更新时间:2024-06-13 00:19:06

Nat*_*ica 5

GCC 在这里实际上是正确的。如果我们遵循[class.member.lookup]中的规则,我们首先有

C 中 N 的查找集,称为 S(N,C),由两个组件集组成:声明集,一组名为 N 的成员;和子对象集,一组子对象,其中找到了这些成员的声明(可能通过 using-declarations)。在声明集中,类型声明(包括注入的类名)被它们指定的类型替换。S(N,C) 计算如下:

所以我们要为类建立一组名称 S(N, C)(在本例中也称为 C)

继续我们的下一段

如果 P 在 C 的完整类上下文中,则声明集是在 C 的范围内从 C 的类说明符之后立即搜索 N 的结果,否则从 P 搜索。如果结果声明集不为空,则子对象集包含 C 本身,计算完成。

当我们查找operator()in 时C,我们没有找到任何东西,所以S(N, C)是空的。然后我们继续下一段

否则(即,C 不包含 N 的声明或结果声明集为空),S(N,C) 最初为空。计算每个直接非依赖([temp.dep.type])基类子对象Bi中N的查找集,并将每个这样的查找集S(N,Bi)依次合并为S(N,C)。

因此,我们将遍历每个基础并添加它的查找集S(N, C),这将我们带到下一个子段

否则,如果 S(N,Bi) 和 S(N,C) 的声明集不同,则合并是不明确的:新的 S(N,C) 是具有无效声明集和子对象并集的查找集套。在随后的合并中,无效的声明集被认为与其他任何不同。

所以,既然没有operator()in C,但它在基类中,那么我们现在有包含基类operator()的无效声明集。然后我们有

搜索的结果是 S(N,T) 的声明集。如果它是无效集合,则程序是非良构的。如果它与从 T 的类说明符之后立即在 T 中搜索 N 的结果不同,则程序是非良构的,不需要诊断。

这告诉我们无效的声明集是格式错误的,因此它是一个错误并且应该无法编译。

解决方法是使用 using 语句将基类函数带入派生类范围

struct C : A, B {
    using A::operator();
    using B::operator();
};

现在将名称带入C其中将为您提供一个有效的名称集,然后可以将其传递给重载决议,以便它选择正确的重载。

更多推荐

不正确,不完整,GCC,std,invocable

本文发布于:2023-04-20 20:45:19,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/hyzx/7123dbbbdbaa7278c533b509174dc3dd.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:不正确   不完整   GCC   std   invocable

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!