28

Using normal C arrays I'd do something like that:

void do_something(int el, int **arr)
{
   *arr[0] = el;
   // do something else
}

Now, I want to replace standard array with vector, and achieve the same results here:

void do_something(int el, std::vector<int> **arr)
{
   *arr.push_front(el); // this is what the function above does
}

But it displays "expression must have class type". How to do this properly?

user2252786
  • 1,627
  • 5
  • 21
  • 32
  • ``int **arr``?? how to assign a 2d array directly? If you need 2d array, ``foo(vector > &arr)``. – gongzhitaao Apr 08 '13 at 22:54
  • 3
    I suppose he was probably trying to pass a pointer to an array not a two dimensional array..correct me if I'm wrong – Mppl Apr 08 '13 at 23:00
  • 2
    Lots of answers but nobody has noticed that it's an array of pointers, not a pointer to an array. They want a `std::vector`. – Joseph Mansfield Apr 08 '13 at 23:20

5 Answers5

36

You can pass the container by reference in order to modify it in the function. What other answers haven’t addressed is that std::vector does not have a push_front member function. You can use the insert() member function on vector for O(n) insertion:

void do_something(int el, std::vector<int> &arr){
    arr.insert(arr.begin(), el);
}

Or use std::deque instead for amortised O(1) insertion:

void do_something(int el, std::deque<int> &arr){
    arr.push_front(el);
}
Jon Purdy
  • 53,300
  • 8
  • 96
  • 166
20

If you define your function to take argument of std::vector<int>& arr and integer value, then you can use push_back inside that function:

void do_something(int el, std::vector<int>& arr)
{
    arr.push_back(el);
    //....
}

usage:

std::vector<int> arr;
do_something(1, arr); 
4pie0
  • 29,204
  • 9
  • 82
  • 118
8
void do_something(int el, std::vector<int> **arr)

should be

void do_something(int el, std::vector<int>& arr)
{
    arr.push_back(el);
}

Pass by reference has been simplified to use the & in C++.

taocp
  • 23,276
  • 10
  • 49
  • 62
  • @taocp, what do you mean by 'Pass by reference has been simplified to use the & in C++.'? – gen Apr 18 '16 at 09:30
  • 1
    @gen It's poor phrasing imho. What really changed in C++ was that it actually has pass-by-reference _at all_. C doesn't. It achieves the same results by passing pointers, and ruling that altering the result of a pointer dereference modifies the pointed value in its original place (not a temp copy). But that's not pass-by-reference. The pointer is passed by value. – underscore_d Jul 04 '16 at 20:46
  • @taocp Any idea, why accepting array of vectors as an argument gave an error: `vector &v[100]`? – subtleseeker Jul 03 '18 at 18:53
3

You can pass vector by reference just like this:

void do_something(int el, std::vector<int> &arr){
    arr.push_back(el);
}

However, note that this function would always add a new element at the back of the vector, whereas your array function actually modifies the first element (or initializes it value).

In order to achieve exactly the same result you should write:

void do_something(int el, std::vector<int> &arr){
    if (arr.size() == 0) { // can't modify value of non-existent element
        arr.push_back(el);
    } else {
        arr[0] = el;
    }
}

In this way you either add the first element (if the vector is empty) or modify its value (if there first element already exists).

Legat
  • 1,379
  • 3
  • 11
  • 20
1

You don't need to use **arr, you can either use:

void do_something(int el, std::vector<int> *arr){
    arr->push_back(el);
}

or:

 void do_something(int el, std::vector<int> &arr){
    arr.push_back(el);
}

**arr makes no sense but if you insist using it, do it this way:

void do_something(int el, std::vector<int> **arr){
    (*arr)->push_back(el);
}

but again there is no reason to do so...

Mppl
  • 941
  • 10
  • 18