20

Is there any problem with my code ?

std::vector<int[2]> weights;
int weight[2] = {1,2};
weights.push_back(weight);

It can't be compiled, please help to explain why:

no matching function for call to ‘std::vector<int [2], std::allocator<int [2]> >::push_back(int*&)’
WoooHaaaa
  • 19,732
  • 32
  • 90
  • 138
  • 9
    This would work with a vector of `std::array`s, `std::vector`s, or `std::pair`s. Your array is decaying to a pointer when it's passed in, which causes problems. – chris Jun 15 '12 at 03:46
  • Thanks, chris. I understand that. – WoooHaaaa Jun 15 '12 at 03:50
  • I think there's a good answer waiting to come out with all the specifics of why it doesn't work, which I would find an interesting and enlightening read. There's more to it than decaying, but I'm not sure what's all there. – chris Jun 15 '12 at 03:54
  • Can this be made to work in C++11 using move semantics? Or is that also doomed? – templatetypedef Jun 15 '12 at 04:13
  • @templatetypedef, Even if it solves pushing it in, there's other issues like copying it. I'm not totally sure whether it would work for pushing or not, though. – chris Jun 15 '12 at 04:21
  • @chris: Pointer-decay isn't a problem. Arrays just aren't copyable. – GManNickG Jun 15 '12 at 04:31
  • @GManNickG, Ah, I wouldn't have thought it would match after going through the function. – chris Jun 15 '12 at 04:37
  • Is this a good answer? http://stackoverflow.com/a/4541707/1155650 – Rohit Vipin Mathews Jun 15 '12 at 04:38

9 Answers9

37

The reason arrays cannot be used in STL containers is because it requires the type to be copy constructible and assignable (also move constructible in c++11). For example, you cannot do the following with arrays:

int a[10];
int b[10];
a = b; // Will not work!

Because arrays do not satisfy the requirements, they cannot be used. However, if you really need to use an array (which probably is not the case), you can add it as a member of a class like so:

struct A { int weight[2];};
std::vector<A> v;

However, it probably would be better if you used an std::vector or std::array.

Jesse Good
  • 50,901
  • 14
  • 124
  • 166
5

You cant do that simply.

It's better you use either of these:

  1. vector <vector<int>> (it's basically a two dimensional vector.It should work in your case)

  2. vector< string > (string is an array of characters ,so you require a type cast later.It can be easily.).

  3. you can declare an structure (say S) having array of int type within it i.e.

    struct S{int a[num]} ,then declare vector of vector< S>

So indirectly, you are pushing array into a vector.

vijay
  • 2,034
  • 3
  • 19
  • 38
5

Array can be added to container like this too.

    int arr[] = {16,2,77,29};
    std::vector<int> myvec (arr, arr + sizeof(arr) / sizeof(int) );

Hope this helps someone.

Dignesh P R
  • 317
  • 3
  • 4
4

Arrays aren't copy constructable so you can't store them in containers (vector in this case). You can store a nested vector or in C++11 a std::array.

Mark B
  • 95,107
  • 10
  • 109
  • 188
3

One possible solution is:

    std::vector<int*> weights;
    int* weight = new int[2];
    weight[0] =1; weight[1] =2;
    weights.push_back(weight);
jalsh
  • 801
  • 6
  • 18
2

You should use std::array instead of simple array:

#include <vector>
#include <array>

std::vector<std::array<int, 2>> weights;
std::array<int, 2> weight = {1, 2};
weights.push_back(weight);

or with a constructor:

std::vector<std::array<int, 2>> weights;
weights.push_back(std::array<int, 2> ({1, 2});
0

Just use

vector<int*>  .That will definitely work.

A relevant discussion on the same topic : Pushing an array into a vector

Community
  • 1
  • 1
Arvind
  • 466
  • 3
  • 9
  • 4
    It'll compile. I don't think it'll do what anybody would rationally want to do! If the array is on the stack, your solution will crash. – Gort the Robot Jun 15 '12 at 04:03
  • Could you tell me Why not? I just tried a simple example,and it worked as expected. The vector just stores the starting address of the array.So, if you want to access the nth element, just look up on the vector,and go to the nth location. – Arvind Jun 15 '12 at 04:10
  • 2
    @Arvind: Right. And everything works until the array leaves scope, or you expect that making a copy of the `vector` makes a deep copy. Then strange things start happening. – Managu Jun 15 '12 at 04:13
  • I misspoke. If the array goes out of scope, you now have a pointer to random memory in your vector. – Gort the Robot Jun 15 '12 at 04:13
  • @Managu,@Steven -Yeah,I realized that as well. Should have mentioned that in the answer. If anyone is using raw pointers in stl containers,they better visualize memory layout first!! :-) – Arvind Jun 15 '12 at 04:22
  • @MrROY Did this answer work for you? If so,you could upvote the same. Someone who comes in here and sees an answer with -1, might not even bother looking at the comments! – Arvind Jun 15 '12 at 10:42
0

Situation like:

int arr[3] = { 1, 2, 3 };
std::vector<int[]> v;
v.push_back(arr);

doesn't work with error "cannot initialize array in vector with .."

This, could be worked well

int * arr = new int[3] { 1, 2, 3 };
std::vector<int*> v;
v.push_back(arr);
Minwoo Yu
  • 360
  • 2
  • 13
-2

To instantiate the vector, you need to supply a type, but int[2] is not a type, it's a declaration.

Roger Dahl
  • 15,132
  • 8
  • 62
  • 82
  • 6
    `int[2]` is a type. It's an array of 2 integers. Arrays are types too, just not as strongly as in other languages. – chris Jun 15 '12 at 04:23
  • If it was a type, wouldn't the declaration be `int[2] myvar;`? – Roger Dahl Jun 15 '12 at 04:45
  • 3
    @RogerDahl: You would think so, but no. You can create templates that would accept `int[2]` as a type([example](http://ideone.com/1mzLP)), it's just the type doesn't happen to meet the requirements of `std::vector`. So it can't be used there. – Benjamin Lindley Jun 15 '12 at 05:00