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

但它会抛出我将在最后包含的极长错误输出。为什么编译器对这两个程序的处理如此不同?这绝对不直观。

这是在我使用 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>

要了解其中一个错误,请想象以下情况:

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包含 s 的数组可以。
所以一个简单的解决方法是:

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

尝试使用vectorofvector代替。

于 2009-09-23T19:57:02.633 回答
1

T所有 STL 容器(包括std::vector<T>)对值类型的要求TAssignable- ISO C++03 23.1[lib.container.requirements]/4-5。Assignable定义如下:

表达式t = u,其中t是 类型T,并且ucv T类型,是有效的,它的返回类型是T&,后置条件是 thatt等价于u

数组不满足这个要求,因为你不能写:

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

你不能这样做的原因是因为上面ab代码片段都根据 4.2[conv.array] 中描述的数组到指针衰减的常用 C++ 规则衰减为指针类型右值。自然,如果不允许在 non-overloaded 的左侧使用右值operator=

于 2009-09-23T20:18:07.067 回答
-1

数组不是 C++ 中的第一类;例如,您不能将它们作为参数传递给函数(它们会衰减为指针,尽管您可以将指针和引用传递数组)。此外,它们没有值语义。

于 2009-11-30T11:28:39.843 回答