-1

I am practicing function pointers in C++. I have written the following code. I have declared an integer vector and added values to it. After that I am passing the values of vector to a function by reference. I am adding the value to each value of vector. After that when I display the content of original vector, the values does not change. Following is the code.

void printValues (int val) {

    cout << val << " ";

}

void ForEach (vector<int> values, void (* func )(int), int inc) {

    for (int value : values) {
        value = value + inc;
        func (value);
    }
}

int main() 
{   
    vector<int> v1;
    cout << "Please enter the values in vector";
    for (int i = 0; i < 5; i++) {
        int val = 0;
        cin >> val;
        v1.push_back(val);
    }



    cout << "value stored in vector :" ;
        ForEach(v1, printValues,8);

    cout << "\nThe content of original vector:";
    for (int i = 0; i < v1.size(); i++) {
        cout << " " << v1[i];
    }



}

I expect the output to be 58,68,78,88,98, but the actual output is 50,60,70,80,90.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
UsamaAjmal
  • 23
  • 2
  • 4
    `vector values` is not passing the parameter by reference, but by value. Same issue for the loop – Jean-François Fabre Jul 11 '19 at 11:41
  • I'm interested to know (if you are willing to say), why you think the above code passes the vector by reference? I'm always interested in why beginners make the mistakes that they do. Apart from anything else it helps me improve my answers to questions here. – john Jul 11 '19 at 12:25
  • @john Usually persons coming from Java or similar language make this mistake, since objects are always passed by reference and not by value in Java. Usually we comment that "C++ is not Java", just to get the point across. – PaulMcKenzie Jul 11 '19 at 12:41
  • @john I recently started practicing C++ so I was told passing using & sign passes arguments by reference. I previously coded in Java. – UsamaAjmal Jul 12 '19 at 11:24
  • @UsamaAjmal That's correct adding `&` passes arguments by reference, but you don't have `&` in your code so you aren't passing by reference. – john Jul 12 '19 at 14:56

1 Answers1

6

vector<int> values is not passing the parameter by reference, but by value. Same issue for the loop (with int value you'll make a copy too). Use &:

void ForEach (vector<int> &values, void (* func )(int), int inc) { // reference for the parameter

    for (int & value : values) {  // reference for the loop
        value += inc;
        func (value);
    }
}

aside:

  • don't use using namespace std. Use std::vector everywhere instead
  • everytime you see a function parameter like in void ForEach (std::vector<int> values,, wonder if the data is "input" or "output". If it's "input", use a constant reference const std::vector<int> &values to avoid a copy and prevent modification at the same time, if it's "output" do std::vector<int> &values to pass by writable reference.
  • in your loop you can use auto: for (auto & value : values) (will adapt to const too) so if the type changes, you don't have to change your loop.
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219