ranged for loop with class instances

Trying to use a ranged for loop with class instances:

I have a class Led, and have declared an array of class instances:

int numLeds = 10;
Led leds[numLeds];

The class has a public Update function, I'd like to use the ranged for loop so I tried:

for (Led led : leds)
		{
		  led.Update();
		}

It compiles and runs but they don't update. I also tried auto instead of Led.

for (auto led : leds)
		{
		  led.Update();
		}

I also tried using other iterator names instead of 'led' like 'L'. Should this work? If not what should?

What does the Led class look like?

Thanks for the reply, sorry mine is late. The sketch is 840 lines long, it’s very much in development. This is the first class I’ve tried to write so feel free to suggest anything about it.
This class is a different one from the one I first mentioned but the same thing happens. Here is the class:

//=============================================================================================================================
class Ripple
{
	//    int stringPos;
	//    uint8_t r;
	//    uint8_t g;
	//    uint8_t b;
	uint8_t step;
	//uint8_t maxSteps;
	//unsigned long updateInterval;
	unsigned long lastUpdate;
	int lowerLed;
	int upperLed;
	unsigned long wait;
	unsigned long startWait;
	uint8_t rampInc;
	//int maxValue;
	uint8_t stepMultiplier;
	//int center = NUM_LEDS / 2;

public:
	//Ripple(uint8_t xPos)
	int center = NUM_LEDS / 2;;
	Ripple()
	{
		//center = xPos;
		step = 0;
		//maxSteps = 5; //random(5, 15);
		updateInterval = 10; //  map(maxSteps, 5, 20, 40, 60);  //  random(25, 75);
		lastUpdate = 0;
		lowerLed = center;
		upperLed = center;
		wait = 1000;
		startWait = 0;
		maxValue = 175;
		stepMultiplier = 255 / maxSteps;  // goes to 0 before maxSteps
	}

	void Update()
	{
		if ((millis() - lastUpdate) >= updateInterval) // time to update:
		{
			if (step == 0)
			{
				//Serial.print("  update function called for ");
				//Serial.println((unsigned)(this), HEX);
				leds[center] = CHSV(color, 255, maxValue);
				step++;
			}
			else if (step == 1)
			{
				leds[center] = CHSV(color, 255, bgLevel);
				int newLowerLed = wrap(center - 1);
				int newUpperLed = wrap(center + 1);
				leds[newLowerLed] = CHSV(color, 255, maxValue);
				leds[newUpperLed] = CHSV(color, 255, maxValue);
				step++;
			}
			else if (step > maxSteps)
			{
				//  clear last leds to background:
				int prevLowerLeadingLed = wrap(center - (step - 1));  // previous lit leading led (step was advanced)
				int prevUpperLeadingLed = wrap(center + (step - 1));
				leds[prevLowerLeadingLed] = CHSV(color, 255, bgLevel);
				leds[prevUpperLeadingLed] = CHSV(color, 255, bgLevel);

				//Serial.print("step = ");
				//Serial.println(step);
				//Serial.print("center = ");
				//Serial.println(center);				
				//Serial.print("prevLowerLeadingLed0 = ");
				//Serial.println(prevLowerLeadingLed);
				//Serial.print("prevUpperLeadingLed0 = ");
				//Serial.println(prevUpperLeadingLed);

				int prevLowerTrailingLed = wrap(center - (step - 1) + 3);  // previously lit trailing leds
				int prevUpperTrailingLed = wrap(center + (step - 1) - 3);
				leds[prevLowerTrailingLed] = CHSV(color, 255, bgLevel);
				leds[prevUpperTrailingLed] = CHSV(color, 255, bgLevel);

				//Serial.print("prevLowerTrailingLed = ");
				//Serial.println(prevLowerTrailingLed);
				//Serial.print("prevUpperTrailingLed = ");
				//Serial.println(prevUpperTrailingLed);

				// wait delay to start next ripple:
				if (millis() - startWait >= wait)
				{
					center = random(10, NUM_LEDS - 10);  //random(20, 60);
					step = 0; //  if max steps restart at top
					wait = random(200, 500);
					//maxSteps = random(5, 10);  // for test 
					maxSteps = random(20, 50);
					stepMultiplier = 255 / maxSteps;
					//Serial.print("maxSteps = ");
					//Serial.println(maxSteps);
					//Serial.print("stepMultiplier = ");
					//Serial.println(stepMultiplier);

				}
			}
			else  // other steps before maxSteps:
			{
				//Serial.println("other steps before maxSteps:");
				int newLowerLed = wrap(center - step);
				int newUpperLed = wrap(center + step);
				//Serial.print("center = ");
				//Serial.println(center);
				//Serial.print("step = ");
				//Serial.println(step);
				//Serial.print("newLowerLed = ");
				//Serial.println(newLowerLed);
				//Serial.print("newUpperLed = ");
				//Serial.println(newUpperLed);

				//Serial.println("clear leds to be lit");
				//clear previously lit leds:
				leds[wrap(newLowerLed + 1)] = CHSV(color, 255, bgLevel);
				leds[wrap(newUpperLed - 1)] = CHSV(color, 255, bgLevel);

				//int lvl1 = pow(fadeRate, step) * value;
				//Serial.print("lvl1 = ");

				//Serial.println(qsub8(maxValue, mul8(step, stepMultiplier)));
				uint8_t lvl1 = qsub8(maxValue, mul8(step, stepMultiplier));

				//            Serial.print("lvl1 = ");
				//            Serial.println(lvl1);
				leds[wrap(newLowerLed)] = CHSV(color, 255, lvl1);
				leds[wrap(newUpperLed)] = CHSV(color, 255, lvl1);

				if (step > 3)
				{
					int newLowerLed = wrap(center - step + 3);
					int newUpperLed = wrap(center + step - 3);

					//set background color:  
					leds[wrap(newLowerLed + 1)] = CHSV(color, 255, bgLevel);
					leds[wrap(newUpperLed - 1)] = CHSV(color, 255, bgLevel);

					//int lvl2 = pow(fadeRate, step - 2) * maxValue;
					//Serial.print("lvl2 = ");
					//Serial.println(qsub8(maxValue, mul8(step - 2, stepMultiplier)));

					uint8_t lvl2 = qsub8(maxValue, mul8(step - 2, stepMultiplier));
					// set color of new trailing leds:
					leds[newLowerLed] = CHSV(color, 255, lvl2);
					leds[newUpperLed] = CHSV(color, 255, lvl2);
				}
				step++;
			}
			TransferToNeoPixelBus();
			NPBStrip.Show();
			//delay(1);
			lastUpdate = millis();
		}
	}

private:
	int wrap(int step)
	{
		// change wrap to Reflect.
		//if (step < 0) return (-1)*step;
		//if (step > NUM_LEDS - 1) return NUM_LEDS - step;

		if (step < 0) return NUM_LEDS + step;
		if (step > NUM_LEDS - 1) return step - NUM_LEDS;
		return step;
	}

};

After the class definition I declare instances with :

Ripple ripples[10];

In loop I call:

		//for (Ripple rip : ripples)
		//{
		//	rip.Update();
		//}

If I call

		for (int i = 0; i < numRipples; i++)
		{
			ripples[i].Update();
		}

instead it works fine.

Where have you EVER seen a c/c++ for loop with this syntax?

for (auto led : leds)

You have to actually learn the language, not just make up your own syntax and hope it works...

Regards,
Ray L.

Ray, look it up.

As presented, your code is copying each element. Add an ampersand…

for (Ripple & rip : ripples)
{
  rip.Update();
}

RayLivingston:
You have to actually learn the language, not just make up your own syntax and hope it works...

perigalacticon:
Ray, look it up.

instant Karma!!!

So @perigalacticon what version of the IDE are you using?

Ranged based for loops work in my version 1.8.2 but I can't recall when support for C++ '11 started.

good eye!

RayLivingston:
Where have you EVER seen a c/c++ for loop with this syntax?

Here...

int junk[] = { 1, 11, 111, 1111, 11111, 2, 22, 222, 2222, 22222 };

void example1( void )
{
  for ( int j : junk )
  {
    Serial.println( j );
  }
}

class Ripple
{
public:
  Ripple( int v ) : _v(v) {}
  
  void Update()
  {
    Serial.print( (unsigned) this );
    Serial.write( '\t' );
    Serial.print( this->_v );
    Serial.println();
  }
private:
  int _v;
};

Ripple ripples[] = { 1, 11, 111, 1111, 11111, 2, 22, 222, 2222, 22222 };

void example2 ( void )
{
  for ( auto & r : ripples )
  {
    r.Update();  
  }
}

void setup( void )
{
  Serial.begin( 250000 );
  Serial.println( F( "========================================" ) );
  example1();
  Serial.println( F( "========================================" ) );
  example2();
  Serial.println( F( "========================================" ) );
}

void loop( void ) { }

And there...
http://en.cppreference.com/w/cpp/language/range-for

BulldogLowell:
good eye!

Sort of. I haven't been working in C++ in ... well ... more than a year. So just spotting such things is just outside my current ability.

I had the foresight to print this within the method (Update). Without the ampersand / reference the value is a constant. Probably the stack location of the temporary variable. If I had not done that I would not have realized what was happening.

without the reference operator the loop is making a copy of the instance local to the loop itself. The member function operates on the copy… the original instance is unaffected.

int Array[] {
  1,2,3,4,5
};

void setup() {
  Serial.begin(9600);
  //
  for (auto a : Array) {
    Serial.println(++a);
  }
  Serial.println();
  for (auto a : Array) {
    Serial.println(a);
  }
  Serial.println();
  for (auto& a : Array) {
    Serial.println(++a);
  }
  Serial.println();
  for (auto a : Array) {
    Serial.println(a);
  }
  
}

void loop() {
  // put your main code here, to run repeatedly:

}

Excellent example and explanation.