【问题标题】:Why can't I inherit the constructors of a virtual base?为什么我不能继承虚拟基础的构造函数?
【发布时间】:2014-09-03 21:04:52
【问题描述】:

我正在尝试使用 g++ 4.9.0 编译以下简单代码:

struct A {
    explicit A(int x) { }
};

struct B : public virtual A {
    using A::A;
};

int main(int argc, char** argv) {
    B b(0);
    return 0;
}

但我收到以下错误:

$ g++ -std=c++11 main.cpp
main.cpp: In function ‘int main(int, char**)’:
main.cpp:10:10: error: use of deleted function ‘B::B(int)’
     B b(0);
          ^
main.cpp:6:14: note: ‘B::B(int)’ is implicitly deleted because the default definition would be ill-formed:
     using A::A;
              ^
main.cpp:6:14: error: no matching function for call to ‘A::A()’
main.cpp:6:14: note: candidates are:
main.cpp:2:14: note: A::A(int)
     explicit A(int x) { }
              ^
main.cpp:2:14: note:   candidate expects 1 argument, 0 provided
main.cpp:1:8: note: constexpr A::A(const A&)
 struct A {
        ^
main.cpp:1:8: note:   candidate expects 1 argument, 0 provided
main.cpp:1:8: note: constexpr A::A(A&&)
main.cpp:1:8: note:   candidate expects 1 argument, 0 provided

我做错了吗?是编译器的bug吗?

【问题讨论】:

标签: c++ gcc4.9


【解决方案1】:

这是GCC bug。 §7.3.3 [namespace.udecl]/p3 要求

在用作成员声明using-declaration中, nested-name-specifier 应命名正在定义的类的基类。如果这样的 using-declaration 命名了一个构造函数,则 nested-name-specifier 应命名正在定义的类的直接基类...

AB 的直接基数,因此允许使用using A::A;

标准规定(§12.9 [class.inhctor]/p8):

一个隐式定义的继承构造函数执行一组 将由用户编写的类的初始化 inline 具有 mem-initializer-list 的类的构造函数,其 只有 mem-initializer 有一个 mem-initializer-id 来命名基础 在使用声明的嵌套名称说明符中表示的类 和如下指定的表达式列表,其中 其函数体中的复合语句为空(12.6.2)。如果说 用户编写的构造函数格式错误,程序是 格式不正确。表达式列表中的每个表达式都具有以下形式 static_cast<T&&>(p),其中p是对应的名称 构造函数参数和Tp的声明类型。

因此对应的用户编写的构造函数是

B::B(int x) : A(static_cast<int&&>(x)) { }

格式正确。

【讨论】:

    【解决方案2】:

    它似乎用 clang 编译,但不是 gcc(至少在我的机器上)。但是,即使使用 gcc,如果您只是将 explicit A() 构造函数添加到基类中,code compiles and works fine 也是如此。

    编辑显然,正如@T.C. 在评论中指出的那样,这是 GCC 中的 known bug

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-24
      • 2015-06-21
      • 2014-08-23
      • 1970-01-01
      • 1970-01-01
      • 2012-04-12
      • 2020-08-05
      • 1970-01-01
      相关资源
      最近更新 更多