2016-10-28 44 views
1

にだから私はこれは本当に短いコードしていない間++グラムでコンパイルされません:++コードそれが打ち鳴らす++

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; 
}; 

をそれが打ち鳴らすの下でうまくコンパイル(3.8.0)を:

$ clang++ test.cpp -std=c++11 

それはグラムの下で失敗しながら++(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クラスにデフォルトのコンストラクタを持つことを期待しています。何故ですか?

編集:これもコピーに失敗します。

Child child(1); 

正常に動作します:このコード:これは一方で

auto child = Child(1); 

はG ++の下で同じエラーを生成します。しかし、私はまだそれを理解していないのですか?

EDIT 2:キーワードvirtualがなければ、それは両方のコンパイラの下で正常に動作します。

+1

興味深い。これはChildの 'virtual'継承を削除した場合、またはChild:' Child(int i):Base(i){} 'のコンストラクタを明示的に定義した場合にコンパイルされます。 – 0x5453

答えて

2

g ++バグだと思います。 N2540から

、私が強調:仮想ベースはデフォルトの初期化をサポートしていない限り

通常、仮想拠点を持つクラスのコンストラクタの定義を継承することは悪い形成される、または仮想ベースがあります直接ベースとなり、転送されるベースとして名前が付けられます。同様に、すべてのデータメンバーおよびその他の直接ベースは、デフォルトの初期化をサポートする必要があります。継承コンストラクタを使用しようとすると、不正な形式になります。注:宣言されていない場合、使用されていません。

私の知る限り、あなたの例は私が強調した条件を正確に満たしているので、動作するはずです。ただし、これは作業草案の変更提案であることに注意してください。最終的な標準に組み込む前に変更されている可能性があります。しかし、私は何か変わった場合、より多くのケースを許し、より多くのケースを禁止することはないと予想しています。

おそらく、実際の標準にアクセスできる人が再確認できます。

関連する問題