Question about storing array in a std::vector in C++

前端 未结 7 1290
灰色年华
灰色年华 2021-01-12 17:07

I am unclear about the following.

First, this code compiles fine:

#include 

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

typedef std         


        
相关标签:
7条回答
  • 2021-01-12 17:22

    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]’

    To understand one of the errors, imagine the following:

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

    As opposed to:

    typedef struct{
        int x1,x2,x3,x4;
    }  ints;
    
    int main()
    {
        ints a;
        ints b = a;
    }
    

    Or even:

    typedef struct{
        int x[4];
    }  ints;
    
    int main()
    {
        ints a;
        ints b = a;
    }
    

    C/C++ arrays cannot be copied via the assignment operator, though structs containing arrays can be.
    So an easy fix is to do:

    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);
    }
    
    0 讨论(0)
  • 2021-01-12 17:29

    The requirement for value type T for all STL containers, including std::vector<T>, is that T is Assignable - ISO C++03 23.1[lib.container.requirements]/4-5. Assignable is defined as follows:

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

    Arrays do not fulfill this requirement, because you cannot write:

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

    The reason why you cannot is because both a and b in the code snippet above decay to pointer-type rvalues according to the usual C++ rules for array-to-pointer decay described in 4.2[conv.array]. Naturally, an rvalue if not permitted on the left side of non-overloaded operator=.

    0 讨论(0)
  • 2021-01-12 17:31

    Under the hood it's doing an assignment and that isn't defined for arrays.

    The pertinent part of the error is

    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]’ 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

    0 讨论(0)
  • 2021-01-12 17:31

    Try boost::array instead of plain arrays. It provides STL-compliant interface around fixed-size arrays, so it can be used inside STL containers. Plus, it implements boundary checking (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);
    }
    
    0 讨论(0)
  • 2021-01-12 17:35

    Arrays are not first class in C++; you cannot pass them as arguments to functions, for example (they decay to pointers, although you can pass pointers and references to arrays). Further, they do not have value semantics.

    0 讨论(0)
  • 2021-01-12 17:37

    It's been a little while since I used C++, but I believe the core problem you're encountering is that arrays don't have the required semantics to get along well with a std::vector<>. I don't have my copy of Stroustrup handy, or I'd give you a reference.

    0 讨论(0)
提交回复
热议问题