6


1

私は以下についてはっきりしていません。

まず、このコードはうまくコンパイルされます。

#含める

typedef struct {int x 1、x 2、x 3、x 4; } int;

typedef std :: vector vec;

int main(){vec v;整数a = {0,1,2,3}; v.push_back(a); }

次のコードはほぼ同じです。

#含める

typedef std :: vector vec;

int main(){vec v; int a [4] = {0,1,2,3}; v.push_back(a); }

しかし、それは私が最後に含めることになる極端な長さのエラー出力をスローします。 なぜコンパイラはこれら2つのプログラムをそれほど異なって扱うのですか? それは絶対に直感的ではありません。

これが私のシステムで投げられたコンパイルエラーで、gを使ってコンパイルしています。

[[email protected] Test]
$ g test2.cpp -o test2 /usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c/4.4.1/i586からインクルードされているファイル。 -redhat-linux / bits / c allocator.h:34、/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c /4.4から。 1 / bits / allocator.h:48、/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c /4.4.1/vectorから62、test2.cpp:2から/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c /4.4.1/ext/new_allocator。 h:メンバ関数 'void __gnu_cxx :: new_allocator <_Tp> :: construct(_Tp *、const _Tp

7 Answer


11


ISO Cは配列newエラーでの初期化を禁止します:配列は中括弧で囲まれた初期化子エラーで初期化されなければなりませんクラス型 'int [4]' _

エラーの1つを理解するために、以下を想像してください。

void main(){int a [4] = {0,1,2,3}; int b [4] = a; }

とは対照的に:

typedef struct {int x 1、x 2、x 3、x 4; } int;

int main(){整数a;整数b = a。 }

あるいは:

typedef struct {int x [4]; } int;

int main(){整数a;整数b = a。 }

C / C配列は代入演算子でコピーすることはできませんが、配列を含む `struct`はコピーできます。 したがって、簡単な解決策は次のとおりです。

typedef struct {int x [4]; } int;

typedef std :: vector vec;

int main(){vec v;整数a = {{{0,1,2,3}}; v.push_back(a); }


6


内部的には代入をしていて、それは配列に対して定義されていません。

エラーの適切な部分は

ここからインスタンス化/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c /4.4.1/bits/vector.tcc:306:* error :配列は中括弧で囲まれたイニシャライザで初期化されなければなりません* /usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c /4.4.1/bits /stl_vector.h:741: 'void std

vector <_Tp、_Alloc> :: push_back(const _Tp)からインスタンス化

'test2.cpp:9:ここからインスタンス化されています/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c /4.4.1/bits/vector .tcc:312:エラー:無効な配列代入


6


プレーンな配列の代わりに boost::arrayを試してください。 これは、固定サイズの配列を囲むSTL準拠のインタフェースを提供するため、STLコンテナ内で使用できます。 加えて、境界チェック( `boost

array :: at`)を実装しています。

#include #include

typedef std :: vector <boost :: array> vec; int main(){vec v; boost :: array va = {0,1,2,3}; v.push_back(va); }


2


私がCを使用してから少し時間が経ちましたが、私が遭遇する中心的な問題は配列が `std

vector <>`とうまくいくために必要な意味論を持っていないということです。 私はStroustrupの私のコピーを便利に持っていないか、または私はあなたに参照を与えるでしょう。


2


代わりに vector`の vector`を使ってみてください。


1


`std

vector`を含むすべてのSTLコンテナに対する値型` T`の要件は、 T`が Assignable`であることです - ISO C 03 23.1 [lib.container.requirements] / 4-5 「割り当て可能」は次のように定義されます。

式「t = u」(式中、「t」は「T」型であり、「u」は型「cv」「T」である)は有効であり、その戻り型は「T」である。 __

次のように書くことはできないため、配列はこの要件を満たしません。

int a [2]、b [2]; a = b;

これができないのは、4.2 [conv.array]で説明されている通常のCの規則から配列へのポインタの減衰に従って、上記のコードスニペットの a`と b`の両方がポインタ型の右辺値に減衰するためです。 当然、オーバーロードされていない `operator =`の左側に右辺値が許されていないならば。


-1


配列はCの最初のクラスではありません。たとえば、それらを関数の引数として渡すことはできません(ポインタや参照を_to_配列に渡すことはできますが、ポインタには変わりません)。 さらに、それらは値意味論を持っていません。