question about void, passing data and print\write

IDE 1.01
UNO

this is a general question not specific to a program yet so just the void is here

goal. when i print or write some info to a serial port or network port etc the write and print commands take a variity of formats such as a byte, a number, a string and even an array.

so as an example i might have this

 lcd.setCursor(10,0);
  lcd.print("ALL in    ");
  lcd.setCursor(5,1);
  lcd.print("Error");

i would like to get it down to something like this

MyLCD(10,0,"ALL in    ");
MyLCD(5,1,"Error");
void MyLCD(byte col, byte row, ?????? info { \\Here is where i am not sure of the proper datatype for the ?????? so it will take anything just like the print/write does
//do additional stuff here

lcd.setCursor(col,row);
lcd.print(info);
}

zarobhr:

MyLCD(10,0,"ALL in    ");

MyLCD(5,1,"Error");
void MyLCD(byte col, byte row, ?????? info { \Here is where i am not sure of the proper datatype for the ?????? so it will take anything just like the print/write does
//do additional stuff here

lcd.setCursor(col,row);
lcd.print(info);
}

Try this:

template<class T>
void MyLCD(byte col, byte row, T t)
{
  lcd.setCursor(col,row);
  lcd.print(t);
}

fungus:

zarobhr:

MyLCD(10,0,"ALL in    ");

MyLCD(5,1,"Error");
void MyLCD(byte col, byte row, ?????? info { \Here is where i am not sure of the proper datatype for the ?????? so it will take anything just like the print/write does
//do additional stuff here

lcd.setCursor(col,row);
lcd.print(info);
}

Try this:

template<class T>

void MyLCD(byte col, byte row, T t)
{
 lcd.setCursor(col,row);
 lcd.print(t);
}

i added that to the code after my void loop

CMSBridge_ino2:6: error: 'T' has not been declared
CMSBridge_ino2.cpp: In function 'void loop()':
CMSBridge_ino2:246: error: invalid conversion from 'const char*' to 'int'
CMSBridge_ino2:246: error: initializing argument 3 of 'void MyLCD(byte, byte, int)'

zarobhr:
i added that to the code after my void loop

CMSBridge_ino2:6: error: 'T' has not been declared

CMSBridge_ino2.cpp: In function 'void loop()':
CMSBridge_ino2:246: error: invalid conversion from 'const char*' to 'int'
CMSBridge_ino2:246: error: initializing argument 3 of 'void MyLCD(byte, byte, int)'

Did you try putting it before the place where it's used?

fungus:

zarobhr:
i added that to the code after my void loop

CMSBridge_ino2:6: error: 'T' has not been declared

CMSBridge_ino2.cpp: In function 'void loop()':
CMSBridge_ino2:246: error: invalid conversion from 'const char*' to 'int'
CMSBridge_ino2:246: error: initializing argument 3 of 'void MyLCD(byte, byte, int)'

Did you try putting it before the place where it's used?

no matter where in code i put template<class T> i get the first error that T has not been declared

Template functions must be defined in a .h file that is then included in the sketch.

Is the template class available in the IDE and in which lib does it live? Fungus (short for Funny Gustavo?)? Thank You, that Print function would solve a lot of GLCD printing that I need to do with the UTFT Library

Bob

The Arduino IDE is weird about function ordering, it rearranges the code in the sketch before it compiles so that forward references work.

There has to be a way to make it work...you just need somebody who knows more then me about the IDE.

PaulS:
Template functions must be defined in a .h file that is then included in the sketch.

No, they can be in the source.
If you include a header, its contents is placed in the spot of the '#include', so its no different to putting it at the top of the sketch. The compiler just needs to see it before its used.

EDIT: PaulS may be right regarding Arduino specifics, it may only copy the function prototype without the previous 'template' line.
Try putting it all on the one line 'template void MyLCD(byte col, byte row, T t);' though before separating. Had no trouble with template objects, spose functions are a different kettle of tea.

You can do 3 different things I tried.

template<class T>
  struct MyLCDHelper{
    static void MyLCD(byte col, byte row, T t)
      {
      
      }
};

//...
MyLCDHelper< bool >::MyLCD( 2, 1, 0 );
struct MyLCDHelper{
  template<class T>
    static void MyLCD(byte col, byte row, T t)
      {
        
      }
};

//...
MyLCDHelper::MyLCD( 2, 1, 0 ); //Template auto type deduction.

MyLCDHelper::MyLCD< bool >( 2, 1, 0 ); //Specific template.

Or a not so safe way.

//This must be the first line of code.
#define TVoid template<class T> void

TVoid MyLCD(byte col, byte row, T t)
      {

      }

pYro_65:
You can do 3 different things I tried.

template<class T>

struct MyLCDHelper{
    static void MyLCD(byte col, byte row, T t)
      {
     
      }
};

//...
MyLCDHelper< bool >::MyLCD( 2, 1, 0 );






struct MyLCDHelper{
  template
    static void MyLCD(byte col, byte row, T t)
      {
       
      }
};

//...
MyLCDHelper::MyLCD( 2, 1, 0 ); //Template auto type deduction.

MyLCDHelper::MyLCD< bool >( 2, 1, 0 ); //Specific template.




Or a not so safe way.



//This must be the first line of code.
#define TVoid template void

TVoid MyLCD(byte col, byte row, T t)
      {

}

i used the not so safe way since it seemed easier, but why is it not so safe??

Not so much for the actual code, just now there are two things to modify when the return type change. Macros can be iffy, search google for examples.

I didn't think of it before, but just use an anonymous namespace.

namespace{
  template<class T>
    void MyLCD(byte col, byte row, T t)
      {

      }
}

//...

void setup(){

    MyLCD( 0, 1, 1 );
}

Seems by far the best as the IDE doesn't generate a prototype for it.

Forget the defines. Using IDE 1.0.2 you can make it work. Example:

HardwareSerial & lcd = Serial;

// function prototype
template<class T> 
void MyLCD(byte col, byte row, T t);

// function definition
template<class T>
void MyLCD(byte col, byte row, T t)
{
//  lcd.setCursor(col,row);
  lcd.print(t);
}

void setup ()  {  }  
void loop ()  {  }

That compiles without errors. I simulated the lcd class with a reference to HardwareSerial, but that's not important right now.

The important thing is to prototype the templated function as I did up there. Then the compiler won't generate another prototype in the wrong place.

this worked to a point, and i may be trying to do more than is possible(easily).

what didnt work is old way lcd.print(z[1],HEX); new way MyLCD(0,1,z[1],HEX); i get

CMSBridge_ino2.ino: In function 'void loop()':
CMSBridge_ino2:152: error: no matching function for call to 'MyLCD(int, int, byte&, int)'

You seem to be passing four parameters to a templated function that expects three.

If you want the function to accept additional arguments such as a format specifier, you need to include those in the declaration and definition.