5

I have a for loop that I want to use multiple times without copy and pasting the code so I'm using a template. Answer I used for the template. The template and loop itself work as intended, but changing a variable from the list inside the function called inside the for loop doesn't work. If I change s.Color inside the 'Test' function, it has not changed outside of that function or the example loop.

So why it is not changed outside of the loop? And how can I make sure it changes outside of the loop?

Template:

void Test(TrafficLight s) {
    switch (s.Type) {
    case hfdWeg:
        s.Color = queueCurrent.HoofdwegColor;
        break;
    case zWeg:
        s.Color = queueCurrent.ZijwegColor;
        break;
    case vtPad:
        s.Color = queueCurrent.VoetpadColor;
        break;
    default:
        std::cout << "\nError";
        break;
    }
}

template<typename Func>
inline void do_something_loop(Func f)
{
    for (std::list<TrafficLight>::iterator i = Lichten.begin(); i !=    Lichten.end(); ++i) {
        TrafficLight & s(*i);
        f(s);
    }
}

Calling the template:

do_something_loop(Test);

The list:

std::list<TrafficLight> Lichten;

TrafficLight class:

class TrafficLight {
private:
public:
    TrafficLight(TrafficLightType type, TrafficLightColor color = R) {
        Color = color;
        Type = type;
    }
    TrafficLightColor Color;
    TrafficLightType Type;
};
gsamaras
  • 71,951
  • 46
  • 188
  • 305
Stefan Teunissen
  • 402
  • 6
  • 19
  • Unrelated to your question, but the temporary variable `s` is not needed in the loop. You can just pass `*i` directly. Or use [`std::for_each`](http://en.cppreference.com/w/cpp/algorithm/for_each) instead of an explicit loop (or use it instead of your function even). – Some programmer dude Nov 23 '17 at 09:33
  • @Someprogrammerdude Wasn't sure if that was possible and forgot to test that, thanks – Stefan Teunissen Nov 24 '17 at 07:57

2 Answers2

5

I suppose:

void Test(TrafficLight s) { ... }

should be:

void Test(TrafficLight& s) { ... }

because now you edit a copy.

So need to pass by reference instead.

Edgar Rokjān
  • 17,245
  • 4
  • 40
  • 67
  • Wow, much easier to solve than I thought. What exactly does the & mean here? – Stefan Teunissen Nov 23 '17 at 09:34
  • 2
    @TeunissenStefan it means that you pass `TrafficLight` object *by reference* so you could edit an actual object inside `Test` function. – Edgar Rokjān Nov 23 '17 at 09:35
  • So if I called the function without using a template I should use the & as well? – Stefan Teunissen Nov 23 '17 at 09:37
  • @TeunissenStefan It seems you could use [a good beginners book or two](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). This is very basic stuff. – Some programmer dude Nov 23 '17 at 09:38
  • @Someprogrammerdude while that would be the most logical thing to do, I can't learn by just reading. For some reason my mind only learns when I do things and make mistakes. – Stefan Teunissen Nov 23 '17 at 09:39
  • 1
    @TeunissenStefan no matter whether you deal with templates or not. Just try to understand the difference between passing objects *by value* and *by reference* - that is the key. Passing by value you edit a copy of object, not the actual object. Passing by reference you edit the object itself. – Edgar Rokjān Nov 23 '17 at 09:42
  • @TeunissenStefan also consider accepting answer which helped you solve the issue... – W.F. Nov 23 '17 at 09:55
  • @W.F. Calm down please. When I wanted to accept it I had to wait a few minutes. Went to the toilet and came back to this reply. – Stefan Teunissen Nov 23 '17 at 10:01
  • 1
    @TeunissenStefan hah first time I was killed by the toilet :) – W.F. Nov 23 '17 at 10:10
2

Change this:

void Test(TrafficLight s)

to this:

void Test(TrafficLight& s)

since you need to pass by reference in order for the changes to persist after the function is terminated.

Your code passes the argument by value (it creates a copy of s inside th body of Test()).

gsamaras
  • 71,951
  • 46
  • 188
  • 305