2009-09-23 9 views
6

以下は不明です。配列をC++のstd :: vectorに格納することについての質問

まず、このコードは罰金コンパイル:

#include <vector> 

typedef std::vector<int[4]> vec; 

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

が、それは私が最後に含まれる極めて長エラー出力をスロー:

#include <vector> 

typedef struct{ 
    int x1,x2,x3,x4; 
} ints; 

typedef std::vector<ints> vec; 

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

次のコードは、同一の近くにあります。なぜコンパイラはこれらの2つのプログラムを違う方法で扱いますか?間違いなく直感的です。それは割り当てをやっているし、それは配列のために定義されていませんボンネットの下

[[email protected] Test]$ g++ test2.cpp -o test2 
In file included from /usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/i586-redhat-linux/bits/c++allocator.h:34, 
       from /usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/bits/allocator.h:48, 
       from /usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/vector:62, 
       from test2.cpp:2: 
/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/ext/new_allocator.h: In member function ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, const _Tp&) [with _Tp = int [4]]’: 
/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/bits/stl_vector.h:737: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = int [4], _Alloc = std::allocator<int [4]>]’ 
test2.cpp:9: instantiated from here 
/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/ext/new_allocator.h:105: error: ISO C++ forbids initialization in array new 
In file included from /usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/vector:69, 
       from test2.cpp:2: 
/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/bits/vector.tcc: In member function ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = int [4], _Alloc = std::allocator<int [4]>]’: 
/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/bits/stl_vector.h:741: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = int [4], _Alloc = std::allocator<int [4]>]’ 
test2.cpp:9: instantiated from here 
/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/bits/vector.tcc:306: error: array must be initialized with a brace-enclosed initializer 
/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/bits/stl_vector.h:741: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = int [4], _Alloc = std::allocator<int [4]>]’ 
test2.cpp:9: instantiated from here 
/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/bits/vector.tcc:312: error: invalid array assignment 
In file included from /usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/i586-redhat-linux/bits/c++allocator.h:34, 
       from /usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/bits/allocator.h:48, 
       from /usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/vector:62, 
       from test2.cpp:2: 
/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/ext/new_allocator.h: In member function ‘void __gnu_cxx::new_allocator<_Tp>::destroy(_Tp*) [with _Tp = int [4]]’: 
/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/bits/vector.tcc:353: instantiated from ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = int [4], _Alloc = std::allocator<int [4]>]’ 
/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/bits/stl_vector.h:741: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = int [4], _Alloc = std::allocator<int [4]>]’ 
test2.cpp:9: instantiated from here 
/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++/4.4.1/ext/new_allocator.h:115: error: request for member ‘~int [4]’ in ‘* __p’, which is of non-class type ‘int [4]’ 

答えて

6

:ここ

はコンパイルするのG ++を使用している私のシステムでスローされるコンパイラエラーです。

エラーの適切な部分はここからインスタンス

ある/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/c++ /4.4.1/bits/vector.tcc:306:エラー:配列は中括弧で囲まれた初期化子で初期化する必要があります /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 &)[_Tp = int [4 ]、_Alloc = std :: allocator] 'test2.cpp:9:ここからインスタンス化/usr/lib/gcc/i586-redhat-linux/4.4.1/../../../../include/ C++/4.4.1/bits/vector.tcc:312:エラー:無効な配列割り当て

+1

これらのテンプレートエラーの仕組みは、コンパイラがタイプに応じてテンプレートをインスタンス化しようとしたときに、結果のコードがコンパイルされます。エラーが発生すると、問題の原因となったコードが書いたコードとどのように関係しているかを理解しようとします。また、あなたが理解できるように、テンプレートのソースコードを知っていることを前提としていますエラー。 –

+0

私はC++ 0x(別名C++ 1x、このレートで)がこのような面白いエラーで終わってしまうかもしれないと聞いたことがあります。 – Brian

+2

@Brainはおそらくそうではありません。改善されたエラーは、C++ 0xから削除されたConceptsを条件にしていました。 –

2

私はC++を使用して以来、少し時間がかかりましたが、あなたが直面しているコア問題は、配列がstd::vector<>でうまくいくために必要なセマンティクスを持っていないと思います。私はStroustrupのコピーを手元に持っていない、または私はあなたにリファレンスを与えるだろう。

6

プレーン配列の代わりにboost::arrayを試してください。固定サイズの配列の周りにSTL準拠のインターフェイスを提供するので、STLコンテナ内で使用できます。さらに、境界チェック(boost::array::at)を実装しています。

#include <boost/array.hpp> 
#include <vector> 

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

また、 'std :: tr1 :: array'(Boostと同じですが、ISO標準化されています)を使用して実装してください。 –

11

error: ISO C++ forbids initialization in array new
error: array must be initialized with a brace-enclosed initializer
error: invalid array assignment
error: request for member ‘~int [4]’ in ‘* __p’, which is of non-class type ‘int [4]’

、エラーのいずれかを理解して次のことを想像するには、次の

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

とは対照的に:

typedef struct{ 
    int x1,x2,x3,x4; 
} ints; 

int main() 
{ 
    ints a; 
    ints b = a; 
} 

あるいは:

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

int main() 
{ 
    ints a; 
    ints b = a; 
} 

配列を含むstructは可能ですが、C/C++配列は代入演算子でコピーできません。
だから、簡単に修正が行うことです。

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

typedef std::vector<ints> vec; 

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

ではなくvectorvectorを使用してみてください。

+1

私は配列のベクトルを使用する正当な欲望があるかもしれないと思う。 (私はおそらくboost :: arrayのようなものを認識していなかったので、おそらくvectorのvectorを使い過ぎたでしょう。) – UncleBens

1

std::vector<T>含むすべてのSTLコンテナ、値型Tの要件は、TAssignableであるということである - ISO C++ 03 23.1 [lib.container.requirements]/4-5。次のようにAssignableが定義されています

Expression t = u , where t is of type T , and u is of type cvT , is valid, its return type is T& , and the post-condition is that t is equivalent to u .

配列あなたが書くことができないため、この要件を満たしていない:

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

に崩壊上記のコードでは、なぜあなたがすることができますされていないため、ab両方の理由4.2 [conv.array]で説明されている配列からポインタへの減衰の通常のC++規則に従って、ポインタ型の右辺値を返します。当然、非過負荷の左側に許可されていない場合の値はoperator=です。

-1

配列はC++では最初のクラスではありません。関数への引数として渡すことはできません(たとえばポインタに壊れますが、配列に渡すことができます)。さらに、それらは価値の意味論をもたない。

関連する問題