代码不能在g++中编译,而在clang++中可以

code does not compile in g++ while it does in clang++

本文关键字:而在 clang++ 编译 不能 g++ 代码      更新时间:2023-10-16

所以我有一个很短的代码:

test.cpp

class Base {
    public:
        Base(int i) {};
};
class Child : public virtual Base {
    using Base::Base;
};
int main(int argc, char * argv[]) {
    auto *child = new Child(1);
    return 0;
};

在clang++(3.8.0)下可以很好地编译:

$ clang++ test.cpp -std=c++11

在g++(5.4.0)下失败:

$ g++ test.cpp -std=c++11
test.cpp: In function ‘int main(int, char**)’:
test.cpp:14:30: error: use of deleted function ‘Child::Child(int)’
     auto *child = new Child(1);
                              ^
test.cpp:8:17: note: ‘Child::Child(int)’ is implicitly deleted because the default definition would be ill-formed:
     using Base::Base;
                 ^
test.cpp:8:17: error: no matching function for call to ‘Base::Base()’
test.cpp:3:9: note: candidate: Base::Base(int)
         Base(int i) {};
         ^
test.cpp:3:9: note:   candidate expects 1 argument, 0 provided
test.cpp:1:7: note: candidate: constexpr Base::Base(const Base&)
 class Base {
       ^
test.cpp:1:7: note:   candidate expects 1 argument, 0 provided
test.cpp:1:7: note: candidate: constexpr Base::Base(Base&&)
test.cpp:1:7: note:   candidate expects 1 argument, 0 provided

由于某些原因,g++期望Base类具有默认构造函数。为什么呢?

EDIT:复制也失败。这段代码:

auto child = Child(1);

在g++下产生相同的错误,而下面:

Child child(1);

工作好。但我还是不明白为什么?

EDIT 2:没有virtual关键字,在两个编译器下都可以正常工作。

我认为这是c++的bug。

选自N2540,由我强调:

通常,继承带有虚基的类的构造函数定义将是错误的,除非虚基支持默认初始化,或者虚基是直接基,并被命名为forward -to基。同样,所有数据成员和其他直接基必须支持默认初始化,否则任何使用继承构造函数的尝试都会是错误的。注意:使用时格式错误,未声明。

就我所知,你的例子完全符合我所强调的条件,所以我认为它应该可行。但请注意,这是一个工作草案变更建议;在纳入最终标准之前,它可能已经改变了。但我预计,如果有什么变化,可能会允许更多的病例,而不是禁止更多的病例。

也许能接触到实际标准的人可以仔细检查一下。