我想結合使用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」語法和括號初始化符,但是沒有提到關於兩者結合的任何內容。 –