6

次のコードがコンパイルされない理由を誰かが理解してくれませんか (g++ 4.8)。私の理解では、PODを初期化できるということです

#include <iostream>
#include <type_traits>

struct my_int
{
  int val_;
};
struct B : public my_int
{
};

int main()
{
  std::cout << std::is_pod<my_int>::value << std::endl;
  std::cout << std::is_pod<B>::value << std::endl;
  const my_int v = { 123 };
  //const B v2 = { 123 }; // does not compile with g++ 4.8.

  return 0;
}

コンパイルは次のとおりです。

g++ -std=c++11 t.cxx
t.cxx: In function 'int main()':
t.cxx:24:21: error: could not convert '{123}' from '<brace-enclosed initializer list>' to 'const B'
   const B v = { 123 };
                     ^

編集:

皆さんの回答のおかげで、集計の初期化の概念を理解できるようになりました。集約が基本クラスを持つことができないという事実を見逃していました。したがって、現在の実装計画を変更する必要があります。私は次のようなことをしたかった:

template < typename T >
struct base_class
{
  int val_;
};
struct MyInt : public base_class<int>
{
  void Func1() {}
};
struct MyDouble : public base_class<double>
{
  void Func2() {}
};

サブクラスを使用して特別なメンバー関数を導入することを避け、コードの重複を避けるために、上記のコードを作り直します。

4

1 に答える 1

6

免責事項

以下は私の解釈であるため、一粒の塩で考えてください。私は決して専門家ではありません。(また、ここで述べた集約 - 初期化子リストの関係についても疑問があります。)

答え

私が知る限り、v2 の集約初期化は非集約クラス タイプ B に適用されるため、これは不可能です。

この回答から、集約には基本クラスが含まれてはならないことがわかります。これによりB、非集約になり、ブレースで囲まれた初期化子リストによって初期化できなくなります。

一方std::is_pod、POD 定義が C++11 で変更されたため、思ったように動作しない場合があります。したがって、POD である型をそのような集約初期化子で初期化できるかどうかはヒントになりません。

添加

ここでは主に集計の初期化について説明していますが、より一般的な用語はリストの初期化であり、制限が緩和されています。ただし、リンクされたリソースで見つかったすべてのケースをチェックすると、リストの初期化を行う可能性はありません(リソースのイニシャライザリストの影響のリストに従う):

  • 初期化リストが空ではありません
  • B集合体ではありません
  • Bの専門ではないstd::initializer_list
  • Bありません
    • イニシャライザリストを取るコンストラクタ
    • リストのシグネチャに適合するコンストラクタ
  • B参照型ではありません
  • B123int を取るコンストラクターがないため、コピー初期化できず、直接初期化できません
  • B初期化子リストが空ではないため、値が初期化されていません
于 2013-09-20T17:44:01.830 に答える