在一个类中,“使用Base :: BaseOfBase;”应该做什么?

黑猫

考虑以下代码:

#include <iostream>
#include <type_traits>

struct A
{
    A(int x) {std::cout << "A(" << x << ")\n";}
};

struct B : A
{
    using A::A;
    B(int x, int y) : A(x) {std::cout << "B(" << x << "," << y << ")\n";}
};

struct C : B
{
    using B::A; // <--

    // C() : B(0,0) {}
};

int main()
{
    C c(1);
}

gcc.godbolt.org

它会在GCC上进行编译并打印A(1),这意味着的一个实例B是“构造的”而不调用构造函数。如果取消注释C(),则C c(1);不再编译(GCC找不到合适的构造函数)

Clang没有说任何有关的信息using B::A;,但是拒绝编译C c(1);(也找不到合适的构造函数)。

MSVC停在using B::A;,基本上就是说您只能从直接基础继承构造函数。

Cppreference没有提到从间接基继承构造函数,因此似乎是不允许的。

是GCC和Clang错误,还是这里发生了什么?

讲故事的人-Unslander Monica

我可以说对于某些GCC继承该构造函数是错误的。主要是因为

[namespace.udecl]

3在用作成员声明的using声明中,每个using声明者的nested-name-specifier应命名所定义类的基类。如果using声明符为构造函数命名,则其nested-name-specifier应命名所定义类的直接基类。

但是最重​​要的是,B::A它甚至根本没有命名构造函数。

[class.qual]

2在不忽略函数名称且嵌套名称说明符指定类C的查找中:

  • 如果在C中查找嵌套名称说明符之后指定的名称是C的注入类名称(子句[class]),或者
  • 在使用声明(即成员声明)的使用声明器中,如果在嵌套名称说明符之后指定的名称与标识符或简单模板ID的模板名称在最后一个组成部分中相同嵌套名称说明符,

该名称被认为是为类C的构造函数命名的。 。—结束说明]这样的构造函数名称只能在命名构造函数的声明的declarator-id或using-declaration中使用。[示例:

struct A { A(); };
struct B: public A { B(); };

A::A() { }
B::B() { }

B::A ba;            // object of type A
A::A a;             // error, A​::​A is not a type name
struct A::A a2;     // object of type A

 —结束示例]

以上两个项目符号均不适用。所以B::A不是构造函数的名称。它只是注入的类名A,已经可以在中使用C我想这应该就像从基类中引入任何旧类型定义一样。即Clang让您定义

C::A a(0);

看起来正确。唯一的用途是if是否B从继承protected A在这种情况下,默认情况下,注入的类名也将不可访问,直到使用using声明提出。修补您在godbolt上的示例可以证实这一点。

MSVC可能对拒绝此代码过于热心。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

netbeans中的Watch进程选项应该做什么?

来自分类Dev

'{default:'1}在系统Verilog中应该做什么?

来自分类Dev

Material-UI中的notched属性应该做什么

来自分类Dev

Vis.js中的“ horizontalScroll”选项应该做什么?

来自分类Dev

ESP.restart() 在 NodeMCU 中究竟应该做什么?

来自分类Dev

自动保存属性应该做什么?如何使用?

来自分类Dev

自动保存属性应该做什么?如何使用?

来自分类Dev

具有移动语义的RAII类中的默认构造函数应该做什么?

来自分类Dev

Xcode中的跳至下一个占位符快捷键应该做什么?

来自分类Dev

处置应该做什么-仅清除资源或执行一些“业务逻辑”?

来自分类Dev

处置应该做什么-仅清理资源或执行一些“业务逻辑”?

来自分类Dev

训练集归一化后,测试集应该做什么

来自分类Dev

在webrtc回调“-(void)peerConnectionOnRenegotiationNeeded:(RTCPeerConnection *)peerConnection”中应该做什么?

来自分类Dev

交互式外壳在孤立的流程组中应该做什么?

来自分类Dev

交互式外壳在孤立的流程组中应该做什么?

来自分类Dev

Debian的/etc/init.d/umountfs中的sed命令应该做什么?

来自分类Dev

我应该扩展系统类型,还是只创建一个静态实用程序类?我怎么知道该做什么?

来自分类Dev

iOS8中用于键盘扩展的父级应用程序应该做什么?

来自分类Dev

在将Python 2.7与Python 3.5一起安装后,使用IDLE编辑选项不可用。应该做什么?

来自分类Dev

在将Python 2.7与Python 3.5一起安装后,“使用IDLE编辑”选项不可用。应该做什么?

来自分类Dev

ASCII字符26应该做什么?

来自分类Dev

--precompile标志应该做什么?

来自分类Dev

在binarysearch中,如果找不到该元素,为什么要从应该做的地方减去一个元素呢?

来自分类Dev

git diff origin master应该做什么?

来自分类Dev

RESETING分离头HEAD应该做什么?

来自分类Dev

Android相机:线程?哪个应该做什么

来自分类Dev

git diff origin master应该做什么?

来自分类Dev

Prolog程序,这个程序应该做什么?

来自分类Dev

交叉验证后我应该做什么?

Related 相关文章

  1. 1

    netbeans中的Watch进程选项应该做什么?

  2. 2

    '{default:'1}在系统Verilog中应该做什么?

  3. 3

    Material-UI中的notched属性应该做什么

  4. 4

    Vis.js中的“ horizontalScroll”选项应该做什么?

  5. 5

    ESP.restart() 在 NodeMCU 中究竟应该做什么?

  6. 6

    自动保存属性应该做什么?如何使用?

  7. 7

    自动保存属性应该做什么?如何使用?

  8. 8

    具有移动语义的RAII类中的默认构造函数应该做什么?

  9. 9

    Xcode中的跳至下一个占位符快捷键应该做什么?

  10. 10

    处置应该做什么-仅清除资源或执行一些“业务逻辑”?

  11. 11

    处置应该做什么-仅清理资源或执行一些“业务逻辑”?

  12. 12

    训练集归一化后,测试集应该做什么

  13. 13

    在webrtc回调“-(void)peerConnectionOnRenegotiationNeeded:(RTCPeerConnection *)peerConnection”中应该做什么?

  14. 14

    交互式外壳在孤立的流程组中应该做什么?

  15. 15

    交互式外壳在孤立的流程组中应该做什么?

  16. 16

    Debian的/etc/init.d/umountfs中的sed命令应该做什么?

  17. 17

    我应该扩展系统类型,还是只创建一个静态实用程序类?我怎么知道该做什么?

  18. 18

    iOS8中用于键盘扩展的父级应用程序应该做什么?

  19. 19

    在将Python 2.7与Python 3.5一起安装后,使用IDLE编辑选项不可用。应该做什么?

  20. 20

    在将Python 2.7与Python 3.5一起安装后,“使用IDLE编辑”选项不可用。应该做什么?

  21. 21

    ASCII字符26应该做什么?

  22. 22

    --precompile标志应该做什么?

  23. 23

    在binarysearch中,如果找不到该元素,为什么要从应该做的地方减去一个元素呢?

  24. 24

    git diff origin master应该做什么?

  25. 25

    RESETING分离头HEAD应该做什么?

  26. 26

    Android相机:线程?哪个应该做什么

  27. 27

    git diff origin master应该做什么?

  28. 28

    Prolog程序,这个程序应该做什么?

  29. 29

    交叉验证后我应该做什么?

热门标签

归档