2014-09-03 2 views
2

나는 ++ 4.9.0를 g을 사용하여 다음과 같은 간단한 코드를 컴파일하기 위해 노력하고있어 :가상베이스의 생성자를 상속받을 수없는 이유는 무엇입니까?

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 컴파일] (http://coliru.stacked-crooked.com/a/24e4b21aeab3cf4d)이 아닌 gcc – quantdev

+2

이것은 GCC 버그 [58751] (https://gcc.gnu.org/bugzilla)입니다. /show_bug.cgi?id=58751). –

+0

SO 관련이 있습니다 (실제로 gcc 파일 보고서의 소스입니다) : http://stackoverflow.com/questions/19399644/inheriting-constructors-and-virtual-base-classes – quantdev

답변

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...

A, 그래서 using A::A;이 허용 B의 직접 염기 것을 요구한다.

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)) { } 

이다 :

표준은 (§12.9 [class.inhctor]/P8)이되도록 지정.

1

gcc가 아니라 clang으로 컴파일 된 것처럼 보입니다 (최소한 내 시스템에서는). 그러나 gcc를 사용하는 경우에도 explicit A() 생성자를 기본 클래스에 추가하기 만하면 code compiles and works fine이됩니다.

EDIT @ T.C.의 의견에서 지적한 것처럼, 이것은 GCC에서 known bug입니다.

관련 문제