8

C ++ 11の均一な初期化を使用して、いくつかのコーナーケースに頭を悩ませようとしていますが、これがなぜなのかわかりません:

struct Base
{
    int x,y,z;
};

struct Derived : Base
{
};
static_assert (std::is_trivial<Base>::value, "Base must be trivial");
static_assert (std::is_trivial<Derived>::value, "Derived must be trivial");

Base b{1, 2, 3};           // 1) This compiles fine
Derived d{10, 20, 30};     // 2) This fails

2とマークされた行は、との両方で「Derived の初期化に一致するコンストラクターがありません」というメッセージで失敗します。clang 3.1g++ 4.7

Derived の場合、コンストラクターを呼び出そうとしても実行されない理由がわかりません (1 行目の場合のように、コンストラクターを呼び出す方法がわかりません。おそらく集約初期化ですか?)。

次の推論のどこかが間違っていますか?:

A) 些細なことで、静的に初期化できることが保証されます

B)静的に初期化するには、実行時にコードを実行する必要がないため、コンストラクターの呼び出しは必要ありません A+B=>自明であることがわかっている型でコンストラクターを呼び出そうとするのはなぜですか?

私は非常に混乱しています....

4

1 に答える 1

11

些細なことは、何かを初期化する方法とは何の関係もありません。重要なのは、Derived型がaggregateであるかどうかですが、そうではありません。

§8.5.1 [dcl.init.aggr] p1

集合体は、ユーザー提供のコンストラクター (12.1)、非静的データ メンバーのブレースまたはイコール初期化子(9.2)、プライベートまたは保護された非静的データ メンバー (条項 11)、基本クラスなし (条項 10)、および仮想関数なし (10.3)。

集計の初期化で初期化できるのは集計のみであるため、リスト初期化 (一様な初期化の正式名称) は適切なコンストラクターを探すことしかできません。

できることはconstexpr、基本クラスに転送するコンストラクターを提供し、 defaulted デフォルト コンストラクターを追加することです。

struct Derived : Base{
    Derived() = default;
    constexpr Derived(int a, int b, int c) : Base{a, b, c}{}
};
于 2012-11-29T12:41:37.400 に答える