为什么我不能继承虚拟基础的构造函数?

时间:2014-09-03 21:04:52

标签: c++ gcc4.9

我尝试使用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

我做错了吗?它是编译器错误吗?

2 个答案:

答案 0 :(得分:4)

这是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):

  

隐式定义的继承构造函数执行set of   由用户编写的类的初始化   该类的inline构造函数,其中包含 mem-initializer-list   只有 mem-initializer 有一个 mem-initializer-id ,用于命名基数   using声明的nested-name-specifier中表示的类   和下面指定的表达式列表,以及   函数体中的复合语句为空(12.6.2)。如果说   用户编写的构造函数将是格式错误的,程序是   病态的。表达式列表中的每个表达式都是表单   static_cast<T&&>(p),其中p是相应的名称   构造函数参数和Tp的声明类型。

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

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

形式良好。

答案 1 :(得分:1)

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

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