-2

If I had code like:

void x(std::set<double> s){
    s.insert(6.0);
}

int main(){
    std::set<double> s;
    s.insert(5.0);
    x(s);
    //Would 6 be seen here? 
    //Or would it only be seen if I had void x(std::set<double>& s)?
}

and does the same answer apply for all the STL containers? and what about user-defined classes? What determines whether any changes to their state would be visible after the modification function has been called?

user997112
  • 29,025
  • 43
  • 182
  • 361
  • 2
    Do you know the difference between pass-by-value and pass-by-reference? If you did, you wouldn't be asking this question. – David G Nov 23 '13 at 00:11

3 Answers3

2

Pass by value (f(T object)) makes a copy of the object (the value) and passes that to the calling function. Thus, the function it was called from does not see the changes.

Pass by reference (f(T &object)) passes the location (the reference) of the object to the calling function. Thus, the function it was called from sees the changes.

Pass by pointer (f(T *object)) behaves in the same way as pass by reference, except you access the methods/variables using -> instead of ..

This applies to any object (STL, user-defined, etc.) or plain data type (e.g. int).

reece
  • 7,945
  • 1
  • 26
  • 28
1

So what is happening here is that when the function X is called, the copy constructor of the STL set makes a copy of each of the elements in the set 's'. If the element being copied is a primitive (i.e. not a pointer) then any changes in X won't be seen outside of X. If the element is a pointer (as would be the case if you were using a user-defined class) then the change would be visible outside X.

The same applies to all STL classes. There is nothing 'magical' about the STL classes, they operate in the same way as a regular class.

Try creating your own 'container' class with a copy constructor and step through the code in a debugger to see what is happening. This will be similar to what is happening in the STL classes.

Nick Weedon
  • 441
  • 5
  • 10
  • By "primitive" did you mean to include a normal user-defined class object, because if that was stored as a value I presume updating that would not be visible outside the function changing it? – user997112 Nov 24 '13 at 02:34
1

6 will not be visible in the set within main.

It would be seen if the signature of x took a reference: void x(std::set& s)

Yes, this holds true for pretty much any STL container. STL containers use value semantics. In your code you pass by value, which means a copy of the container is made. This is a potentially very expensive operation, but means the recipient can change the object they get, without worrying about affecting the caller's state. Still, it is rarely done and often an error when it does appear.

For a function to change the state of one of its parameters, you need to either pass by reference, or pass a pointer to the object to be changed (which is what C programmers do, but c++ people mostly avoid).

RichardPlunkett
  • 2,998
  • 14
  • 14