2014-09-03 84 views
2

我試圖用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 

難道我做錯了什麼?這是一個編譯器錯誤?

+0

hm,[clang compiles it](http://coliru.stacked-crooked.com/a/24e4b21aeab3cf4d),而不是gcc – quantdev 2014-09-03 21:07:31

+2

這是GCC錯誤[58751](https://gcc.gnu.org/bugzilla /show_bug.cgi?id=58751)。 – 2014-09-03 21:09:50

+0

SO關聯有(實際上是gcc文件報告的來源):http://stackoverflow.com/questions/19399644/inheriting-constructors-and-virtual-base-class – quantdev 2014-09-03 21:15:11

回答

4

這是一個GCC bug。 §7.3.3[namespace.udecl]/P3要求

In a using-declaration used as a member-declaration, the nested-name-specifier shall name a base class of the class being defined. If such a using-declaration names a constructor, the nested-name-specifier shall name a direct base class of the class being defined...

AB直接基,所以using A::A;是允許的。

的標準規定(§12.9[class.inhctor]/P8):

An implicitly-defined inheriting constructor performs the set of initializations of the class that would be performed by a user-written inline constructor for that class with a mem-initializer-list whose only mem-initializer has a mem-initializer-id that names the base class denoted in the nested-name-specifier of the using-declaration and an expression-list as specified below, and where the compound-statement in its function body is empty (12.6.2). If that user-written constructor would be ill-formed, the program is ill-formed. Each expression in the expression-list is of the form static_cast<T&&>(p) , where p is the name of the corresponding constructor parameter and T is the declared type of p .

因此相應的用戶編寫的構造函數是

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

這是良好的形成。

1

它似乎與clang編譯,但不是gcc(至少在我的機器上)。即使使用gcc,但是,如果您只需將基本類的構造函數添加到code compiles and works fine即可。

編輯很顯然,正如@T.C評論中指出的,這是GCC中的known bug

相關問題