0

I apologize if this question has already been answered (I tried searching around, but couldn't find anything quite the same, and similar questions' solutions didn't work), but how do I pass an object (in this case, a vector of objects) and have the function edit those values without returning anything?

Example:

void incVector(std::vector<int> vec)
{
    for (auto l = 0; l < int(vec.size()); l++)
    {
        vec[l]++;
    }
}

int main()
{
    std::vector<int> vec;
    vec.push_back(1);
    vec.push_back(2);
    for (auto l = 0; l < int(vec.size()); l++)
    {
        std::cout << vec[l];    //Output: "12"
    }

    incVector(vec);

    for (auto l = 0; l < int(vec.size()); l++)
    {
        std::cout << vec[l];    //Output: "12"
        //This output should be "23"
    }
}

Obviously, what I'm actually using this for is much more complex, but this is enough of an example to get the point of what I'm trying to do across. In the actual project, it's a rabbit hole of different functions, some of which return things while others don't, so having it simply return the vector isn't an option.

I have tried making incVector accept a reference to a vector, a pointer to a vector, a pointer to a reference to a vector, and a pointer to a pointer to a vector (which are solutions that seemed to work for other similar questions) but none of those are working for me.

EDIT: God, I feel stupid. I swear I'd tried using a reference before and it didn't work. Yet now, trying it again works just fine. Sorry! ^^;

2 Answers2

3

you pass the vector by value, thus modifications are purely local: change prototype of your function to:

void incVector(std::vector<int> &vec)

to pass by reference and get the one from main modified

user0042
  • 7,917
  • 3
  • 24
  • 39
OznOg
  • 4,440
  • 2
  • 26
  • 35
3

Take the argument by reference. You can also use a modern for-loop.

void incVector(std::vector<int>& vec)
{
    for (auto& l : vec)
    {
        ++l;
    }
}

But you don't actually need to do any of this. Applying an operation on each element of the vector can be done easily using a standard algorithm (std::for_each) and a lambda function that takes a reference to the vector's element:

#include <algorithm>
// ...

std::for_each(vec.begin(), vec.end(), [](int& l){ ++l; });

for_each is going to call the lambda for each element in the vector and pass it as the argument. Since you take the argument by reference (int&), incrementing it will increment the actual element contained in the vector.

The key point to take away from this however, is that when you want to give a new name to an object that already exists, you use a reference. Those are declared with & before their identifier:

int i = 0;
int &i_ref = i;

Here, i_ref is a reference to i, meaning it's just another name for i. Modifying i_ref is the same as modifying i.

The same applies to function arguments. If a function argument is a reference, it means it's another name for the object that was passed to the function. Modifying the reference is the same as modifying the object that was passed to the function.

Nikos C.
  • 50,738
  • 9
  • 71
  • 96