在clang ++

时间:2016-10-28 15:14:58

标签: c++ c++11 g++ clang++

所以我有这个非常简短的代码:

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类具有默认构造函数。那是为什么?

编辑:这也无法复制。这段代码:

auto child = Child(1);

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

Child child(1);

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

编辑2:如果没有virtual关键字,它可以在两个编译器下正常工作。

1 个答案:

答案 0 :(得分:2)

我认为这是一个g ++错误。

来自N2540,我强调:

  

通常,继承具有虚拟基础的类的构造函数定义将是格式错误的,除非虚拟基础支持默认初始化,或虚拟基础是直接基础,并命名为base转发到。同样,所有数据成员和其他直接库都必须支持默认初始化,否则任何使用继承构造函数的尝试都将是错误的。注意:使用时形成不良,未声明。

据我所知,你的例子完全符合我所强调的条件,所以我认为它应该有效。但请注意,这是一份工作草案变更提案;它可能在纳入最终标准之前已经改变。但我希望如果发生任何变化,它可能会允许更多案件,而不是禁止更多案件。

也许有权访问实际标准的人可以仔细检查。