我想结合使用C++ 11直接数据成员初始化和“using”语法来继承基类的构造函数。现在使用gcc 5.4.0(在Ubuntu 16.04上),我观察到一个奇怪的错误,如果数据成员类型没有默认构造函数。它可能比较容易找上了以下最低例如,当明白:构造函数继承和直接成员初始化
#include <iostream>
struct Foo {
Foo(int arg) { std::cout << "Foo::Foo(" << arg << ")" << std::endl; }
};
struct Base {
Base(int arg) { std::cout << "Base::Base(" << arg << ")" << std::endl; }
};
struct Derived : public Base {
using Base::Base;
Foo foo{42};
};
int main() {
Derived derived{120};
}
此代码编译并与铛预期的行为执行。用gcc编译不能通过,因为编译器删除构造Derived::Derived(int)
:
ttt.cpp: In function ‘int main()’:
ttt.cpp:17:22: error: use of deleted function ‘Derived::Derived(int)’
Derived derived{120};
^
ttt.cpp:12:15: note: ‘Derived::Derived(int)’ is implicitly deleted because the default definition would be ill-formed:
using Base::Base;
^
ttt.cpp:12:15: error: no matching function for call to ‘Foo::Foo()’
ttt.cpp:4:3: note: candidate: Foo::Foo(int)
Foo(int arg) { std::cout << "Foo::Foo(" << arg << ")" << std::endl; }
^
ttt.cpp:4:3: note: candidate expects 1 argument, 0 provided
ttt.cpp:3:8: note: candidate: constexpr Foo::Foo(const Foo&)
struct Foo {
^
ttt.cpp:3:8: note: candidate expects 1 argument, 0 provided
ttt.cpp:3:8: note: candidate: constexpr Foo::Foo(Foo&&)
ttt.cpp:3:8: note: candidate expects 1 argument, 0 provided
如果我添加一个默认的构造的Foo这样的:
Foo() { std::cout << "Foo::Foo()" << std::endl; };
也可以GCC编译它。代码的行为完全一样,特别是Foo的默认构造函数永远不会被执行。
所以我的问题是现在,这是有效的C + + 11?如果是的话,我可能已经在gcc中发现了一个bug。否则,gcc和clang都不应该给我一个错误消息,说明这是无效的C++ 11?
编辑问题后很好地回答@ vlad-from-moscow:这个bug似乎也出现在gcc 6.2中,所以我会提交一个bug报告。
2日编辑:已经有一个错误,我没有在第一搜索发现:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67054
我在cppreference.com等网页上找不到任何关于此的内容。在那里描述了“using”语法和括号初始化符,但是没有提到关于两者结合的任何内容。 –