Clangのドキュメントはそれをきちんと説明しています
クラスまたは構造体にユーザー定義のデフォルト コンストラクターがない場合、C++ では、このような const インスタンスをデフォルトで構築することはできません ([dcl.init]、p9)。
次のコードには のユーザー定義のデフォルト コンストラクターがありますが、(新しい C++11 継承コンストラクター機能を使用して)すべてのコンストラクターを明示的に継承しているにもかかわらずBase
、g++ と Clang は のデフォルト コンストラクターがユーザー定義であるかどうかについて意見が分かれています。Derived
Derived
Base
#include <iostream>
class Base
{
public:
Base(): b_(0) {} // look! user-defined default constructor
void print() const { std::cout << b_ << "\n"; }
private:
int b_;
};
class Derived
:
public Base
{
using Base::Base; // does this constitute a user-defined default constructor?
};
int main()
{
Base const b;
b.print(); // 0 for g++ & CLang
Derived const d;
d.print(); // 0 for g++, Clang: "default initialization of an object of const type 'const Derived' requires a user-provided default constructor"
}
g++ 4.8 はこのコードを問題なく受け入れますが、Clang 3.3 は受け入れません。規格は何と言っていますか?
注: のユーザー定義のデフォルト コンストラクターがBase
ない場合、g++ 4.8 も Clang 3.3 も受け入れませんBase const b;
(たとえば、g++ 4.7.2 は以前にそれを受け入れていました)。g++ がルールを知っていることを考えると、これは、g++ がデフォルトのコンストラクターをDerived
ユーザー定義と見なしていることを意味すると思います。しかし、Clang 3.3 はそうではないと考えています。
更新: 0/1 引数コンストラクターは継承されないという @JesseGood の回答に基づいて、Base
コンストラクターを次のように変更しようとしました
Base(int b = 0, void* = nullptr): b_(b) {}
ただし、Clang エラーは解決されません。