113
class C 
{
public:
 C() : arr({1,2,3}) //doesn't compile
{}
    /*
    C() : arr{1,2,3} //doesn't compile either
{}
    */
private:
 int arr[3];
};

=その理由は、配列は構文でのみ初期化できるためだと思います。つまり、次のとおりです。

int arr[3] = {1,3,4};

質問

  1. どうすればやりたいことを実行できますか (つまり、コンストラクターで配列を初期化します (本体に要素を割り当てません))。それは可能ですか?
  2. C++03 標準は、ctor 初期化子での集計 (配列を含む) の初期化について特別なことを述べていますか? または、上記のコードの無効性は、他のいくつかのルールの結果ですか?
  3. C++0x 初期化リストは問題を解決しますか?

PSベクトル、boost::arrays、および配列に対するそれらの優位性については言及しないでください。

4

7 に答える 7

62
  1. どうすればやりたいことを実行できますか (つまり、コンストラクターで配列を初期化します (本体に要素を割り当てません))。それは可能ですか?

はい。配列を含む構造体を使用しています。あなたはそれについてすでに知っていると言いますが、私にはその質問がわかりません。そうすれば、本体で割り当てを行うことなく、コンストラクターで配列を初期化できます。これが何をするかboost::arrayです。

C++03 標準は、ctor 初期化子での集計 (配列を含む) の初期化について特別なことを述べていますか? または、上記のコードの無効性は、他のいくつかのルールの結果ですか?

mem-initializer は直接初期化を使用します。そして、条項8の規則は、この種のことを禁じています. 次のケースについては正確にはわかりませんが、一部のコンパイラでは許可されています。

struct A {
  char foo[6];
  A():foo("hello") { } /* valid? */
};

詳細については、この GCC PRを参照してください。

C++0x 初期化リストは問題を解決しますか?

はい、彼らがやります。しかし、あなたの構文は無効だと思います。リストの初期化を開始するには、ブレースを直接使用する必要があります

struct A {
  int foo[3];
  A():foo{1, 2, 3} { }
  A():foo({1, 2, 3}) { } /* invalid */
};
于 2010-10-30T09:33:17.140 に答える
35

C++98 は、配列をゼロにする (または非 POD 要素の場合は、値を初期化する) 以外の直接的な構文を提供しません。そのためには、 と書くだけC(): arr() {}です。

C++0x 集約の初期化の制限について、Roger Pate は間違っていると思いますが、私はそれを調べたり調べたりするのが面倒で、どうでもいいことですよね? 編集:ロジャーは「C++03」について話していましたが、「C++0x」と読み違えました。ごめんなさい、ロジャー。☺</p>

現在のコードに対する C++98 の回避策は、配列を でラップし、structその型の静的定数から初期化することです。いずれにせよ、データはどこかに存在する必要があります。カフを外すと、次のようになります。

class C 
{
public:
    C() : arr( arrData ) {}

private:
     struct Arr{ int elem[3]; };
     Arr arr;
     static Arr const arrData;
};

C::Arr const C::arrData = {{1, 2, 3}};
于 2010-10-30T09:26:43.307 に答える
9

回避策:

template<class T, size_t N>
struct simple_array { // like std::array in C++0x
   T arr[N];
};


class C : private simple_array<int, 3> 
{
      static simple_array<int, 3> myarr() {
           simple_array<int, 3> arr = {1,2,3};
           return arr;
      }
public:
      C() : simple_array<int, 3>(myarr()) {}
};
于 2010-10-30T09:25:38.887 に答える
4
  1. いいえ、残念ながら。
  2. 文法で許可されていないため、希望する方法ではできません(詳細は後述)。ctor のような初期化のみを使用できます。ご存知のように、配列内の各項目の初期化には使用できません。
  3. 多くの有用な方法で全面的に初期化を一般化するため、私はそう信じています。しかし、詳細についてはわかりません。

C++03 では、集計の初期化は以下のような構文でのみ適用されます。これは別のステートメントである必要があり、ctor 初期化子には適合しません。

T var = {...};
于 2010-10-30T08:56:09.487 に答える
2

どうですか

...
  C() : arr{ {1,2,3} }
{}
...

?

g++ 4.8 で正常にコンパイル

于 2014-05-12T18:34:06.650 に答える