Call of overloaded function is ambiguous?

I've separated my code into tabs in the ide (no extensions because I don't have time to muck about with making 50 header files), and so far things seem to be working fine. I had to add my default parameters to my function definitions because the ide doesn't handle those, but that seems to work fine.

Except in this case:

      for (int x = 1; x <= count; x++) {
          led::set(x, 1.0, true); // Turn LEDs on instantly because we are flipping them on and off so fast the would be dim otherwise.
        }
 
        for (int x = (count+1); x <= 15; x++) {
          led::set(x, 0);
        }

The first set there is giving me issues. Here's the declaration:

 namespace led {
     
      byte modules;          // Number of LED modules connected.  With current LED modules, there is a maximum of 6.  Defined in config.txt.  
  
      int * scale;           // Scaling factor for LED brightness.  Used when say, you want to be able to adjust the brightness of the powercell without changing all the code that assumes the max desired brightness is 1.0. 
                             // Valid range in config.txt is [0..1] but this is converted to range [0..4095] when stored so as to make the math simpler when calcualting LED brightnesses.   
     
      float * currentValue;  // Current LED brightness. [0..1]  
      float * targetValue;   // Target LED brightness. [0..1]
      float * speed;         // How fast LED should move towards target value.  1.0 = Starting from 0, LED would reach full brightness in one second.  Set speed to -1 to change brightness instantly.                       
      
      byte * data;           // LED data is stored as a string of 12 bit LED values.  There are 3 bytes for every two LEDs.  We store it this way because the data does not need to be altered when we are shifting it out to the TLC5947s.  Modifying the data with bit shifts would be very expensive and there is a lot of data to move.
   
      int frameTime = 22;    // The number of milliseconds between each update of the LEDs.  1000 / 24 = 24fps. (Changed to a global so LED framerate can be set in config file.)
   
      void init();           // This function allocates the memory and sets up the LEDs. 
   
      void set(int index, float value, boolean instant = false); 
      float get(int index, boolean target = false);
      
      //void toggle(); // Used to blink an LED.
      
  } // 15.5 bytes per LED.  At 6 LED modules max, that's 2232 bytes max.  Could halve that if I used fixed point for LED values.

The optional parameter of get works fine. But not the one in set. What gives?

Here's the functions themselves:

/*
This function sets or animates the brightness of an LED.

Parameters:
  index   - The LED whose brightness you wish to change.  Valid range: [1..led::modules*24]
  value   - The desired brightness level.  Valid range: [0..1]
  instant - An optional parameter which forces the LEDs value to change instantly regardless of the set speed. 
*/

void led::set(int index, float value, boolean instant) {
 
  //if (index < 1) || (index > leds) { } // Check to make sure the LED index is within the allowed range.  If not, log the error and halt.
  
  led::targetValue[index-1] = value;  
  if ((speed < 0) || (instant)) { led::currentValue[index-1] = value; } // Set LED immediately to desired brightness. 
    
}


/*
This function returns an LEDs value. 
By default, it returns the current value, but if you set target to true, it will return the target value instead.
The current value of an LED changes over time at a speed defined by the LEDs speed.  If you set an LED but the speed is not -1, then currentValue will change over time to match the targetValue you set.
The targetValue on the other hand is set immediately regardless of speed.  But it may not represent the LED's current level of brightness.
*/

float led::get(int index, boolean target) {
  
  //if (index < 1) || (index > (LEDMODULES*24)) { } // Check to make sure the LED index is within the allowed range.  If not, log the error and halt.
  
  if (target) { 
    return led::targetValue[index-1]; 
  } else { 
    return led::currentValue[index-1]; 
  }
  
}

Btw, the actual error message says "call of overloaded set(int&, double, int)".

Why does the first int have an ampersand after it?

Also, why does boolean seem to be defined as an int, when a byte would suffice?

What's overloaded about it?

I turned that into a sketch that compiles. And compiles it does, without errors:

 namespace led {
     
      byte modules;          // Number of LED modules connected.  With current LED modules, there is a maximum of 6.  Defined in config.txt.  
  
      int * scale;           // Scaling factor for LED brightness.  Used when say, you want to be able to adjust the brightness of the powercell without changing all the code that assumes the max desired brightness is 1.0. 
                             // Valid range in config.txt is [0..1] but this is converted to range [0..4095] when stored so as to make the math simpler when calcualting LED brightnesses.   
     
      float * currentValue;  // Current LED brightness. [0..1]  
      float * targetValue;   // Target LED brightness. [0..1]
      float * speed;         // How fast LED should move towards target value.  1.0 = Starting from 0, LED would reach full brightness in one second.  Set speed to -1 to change brightness instantly.                       
      
      byte * data;           // LED data is stored as a string of 12 bit LED values.  There are 3 bytes for every two LEDs.  We store it this way because the data does not need to be altered when we are shifting it out to the TLC5947s.  Modifying the data with bit shifts would be very expensive and there is a lot of data to move.
   
      int frameTime = 22;    // The number of milliseconds between each update of the LEDs.  1000 / 24 = 24fps. (Changed to a global so LED framerate can be set in config file.)
   
      void init();           // This function allocates the memory and sets up the LEDs. 
   
      void set(int index, float value, boolean instant = false); 
      float get(int index, boolean target = false);
      
      //void toggle(); // Used to blink an LED.
      
  } // 15.5 bytes per LED.  At 6 LED modules max, that's 2232 bytes max.  Could halve that if I used fixed point for LED values.
  
  
  /*
This function sets or animates the brightness of an LED.

Parameters:
  index   - The LED whose brightness you wish to change.  Valid range: [1..led::modules*24]
  value   - The desired brightness level.  Valid range: [0..1]
  instant - An optional parameter which forces the LEDs value to change instantly regardless of the set speed. 
*/

void led::set(int index, float value, boolean instant) {
 
  //if (index < 1) || (index > leds) { } // Check to make sure the LED index is within the allowed range.  If not, log the error and halt.
  
  led::targetValue[index-1] = value;  
  if ((speed < 0) || (instant)) { led::currentValue[index-1] = value; } // Set LED immediately to desired brightness. 
    
}


/*
This function returns an LEDs value. 
By default, it returns the current value, but if you set target to true, it will return the target value instead.
The current value of an LED changes over time at a speed defined by the LEDs speed.  If you set an LED but the speed is not -1, then currentValue will change over time to match the targetValue you set.
The targetValue on the other hand is set immediately regardless of speed.  But it may not represent the LED's current level of brightness.
*/

float led::get(int index, boolean target) {
  
  //if (index < 1) || (index > (LEDMODULES*24)) { } // Check to make sure the LED index is within the allowed range.  If not, log the error and halt.
  
  if (target) { 
    return led::targetValue[index-1]; 
  } else { 
    return led::currentValue[index-1]; 
  }
  
}  

const int count = 42;

void setup ()
  {
   for (int x = 1; x <= count; x++) {
            led::set(x, 1.0, true); // Turn LEDs on instantly because we are flipping them on and off so fast the would be dim otherwise.
          }
   
          for (int x = (count+1); x <= 15; x++) {
            led::set(x, 0);
          }  
        
  }  // end of setup
  
void loop ()
  {
    
  }  // end of loop

Ah. I found the issue. I had been trying to put my LED code in a .cpp and .h file instead of a new tab earlier today and I left the header file I was no longer using included in a couple places.

Now, I had chosen DELETE from the tab menu, so the file shouldn't even be there, but I guess DELETE doesn't mean DELETE and is more like "close tab".

Seems to be working now though. I guess that int on the boolean parameter must have been the old speed parameter I had. Thanks for the assistance. :slight_smile:

Wait a minute. The file ISN'T there.

How the hell did it include it when it's not in the directory? I didn't delete it just now. All I did was remove the includes and the program compiled fine after.

Post the actual error/s not a taste, overloaded means multiple names, different definitions. You need to work out where the multiple declaration is as you do not declare index as a reference ( & ) in the files you provide.

Change the name to set1 so you can see if there is really a second, otherwise... more info, also until you understand headers, no definitions in headers, only declarations:

.h
int frameTime = 22;

extern int frameTime;

.cpp

extern int frameTime = 22;

Try placing the function in the namespace, as you are defining its contents, not accessing a member.

namespace led{
  void set(int index, float value, boolean instant) {
 
    //if (index < 1) || (index > leds) { } // Check to make sure the LED index is within the allowed range.  If not, log the error and halt.
  
    targetValue[index-1] = value;  
    if ((speed < 0) || (instant)) { currentValue[index-1] = value; } // Set LED immediately to desired brightness. 
    
  }
};

For new post:
Left over junk on compilation folder, when compiling for due and avr the delay function explodes on the avr due to the 'due' yied addition and units with the same name.

Yep, sure enough I put #include "leds.h" back in the main program I get the error again, but there is no such file in my project directory. It is in one of my other project directories (an earlier save of this project) but definitely not this one and I never moved the file anywhere after creating it from within the ide.

And I just deleted it from the earlier save directory and I still get the error. I searched all the directories and there's no other copy of the file. What the hell?

So what you're saying is there's a temp folder somewhere where this file has been copied and it's not getting cleaned out before I compile a completely different project? And that this is actually known to cause issues when compiling for different platforms? I kinda figured as much but that's not good.

In my particular case it was, but if you compiled the app before removing stuff then there may still be an object file with the old definition inside. Turn on verbose output ( preferences in IDE ) and it will show the compilation path in the output window on compilation.

Find it and delete its entire contents, mine looks like this:

C:\Users\Chris\AppData\Local\Temp\build3108708783782727624.tmp/

Restarting the IDE may give a new temp folder, something to investigate.

scswift:
So what you're saying is there's a temp folder somewhere where this file has been copied and it's not getting cleaned out before I compile a completely different project? And that this is actually known to cause issues when compiling for different platforms? I kinda figured as much but that's not good.

That wouldn't totally surprise me. I believe the latest IDE tries to not recompile .o files if it doesn't have to, and thus it must leave files lying around in the temporary folder. And if it previously copied in a .h file, which you then remove from the project, the copy may well still be there.

Still, it's a bit of a bug (of yours) to include a .h file which doesn't exist. It's just that the error you got was confusing. To say the least.

That appears to be a bug in the IDE for which I have submitted a report:

if (! Attendance.publish(ID)) {
Serial.println(F("Failed"));
} else {
Serial.println(F("Sent!"));
}
}

error exit status 1

call of overloaded 'publish(char&)' is ambigous