6

以下について不明です。

まず、このコードは正常にコンパイルされます。

#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);
}

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

#include <vector>

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

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

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

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

[mattg@pigott 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]’
4

7 に答える 7

11

エラー: ISO C++ は配列での初期化を禁止しています 新しい
エラー: 配列は中かっこで囲まれた初期化子で初期化する必要があります
エラー: 無効な配列割り当て
エラー: 非クラスの '* __p' のメンバー '~int [4]' の要求タイプ 'int [4]'<br>

エラーの 1 つを理解するには、次のことを想像してください。

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;
}

C/C++ 配列は代入演算子を介してコピーできませんが、struct配列を含む はコピーできます。
したがって、簡単な修正は次のとおりです。

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);
}
于 2009-09-23T19:31:44.957 に答える
6

内部では割り当てを行っており、それは配列に対して定義されていません。

エラーの該当部分は

ここからインスタンス化 /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&) [with _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:エラー: 無効な配列割り当て

于 2009-09-23T19:18:47.500 に答える
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);
}
于 2009-09-23T19:28:34.590 に答える
2

C++ を使用してから少し時間が経ちましたが、あなたが直面している中心的な問題は、配列がstd::vector<>. Stroustrup のコピーを手元に持っていないか、参照を提供します。

于 2009-09-23T19:19:39.613 に答える
2

代わりにvectorofを使用してみてください。vector

于 2009-09-23T19:57:02.633 に答える
1

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

t = utは型Tでありu、型はcv Tであり、有効であり、その戻り型はT&であり、事後条件は。tと同等uです。

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

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

できない理由は、上記のコードスニペットの両方がab4.2[conv.array]で説明されている配列からポインターへの減衰に関する通常のC++ルールに従ってポインター型の右辺値に減衰するためです。当然、オーバーロードされていない左側で許可されていない場合の右辺値operator=

于 2009-09-23T20:18:07.067 に答える
-1

配列は C++ のファースト クラスではありません。たとえば、それらを引数として関数に渡すことはできません (配列へのポインターと参照を渡すことはできますが、それらはポインターに減衰します)。さらに、それらには値のセマンティクスがありません。

于 2009-11-30T11:28:39.843 に答える