A function to handle multiple datatypes

Hello all,

If there any way that I can write a function that will accept multiple datatypes?
This is what I am trying to do:
I want a function that I can pass either a string of characters or an integer or an object and it will treat it as a stream of bytes so that I can write them out to the serial port one byte at a time. The function will also include things like byte stuffing, but I can deal with that later.

I remember that there was an EEPROMWriteAnything function that used template and things like that but I can't figure out how to adapt it to my needs. I tried and all I get is errors; things like "expected ',' or '...' before '&' token" and "error: ISO C++ forbids declaration of 'T' with no type"

Help?

All you neediest function overloading. Write both functions andngive them the same name and the compiler will figure it out based on the data type of the argument.

Certainly....

void SendIt( void * const raw, unsigned size )
{
  uint8_t const * rover;

  rover = (unit8_t const *) raw;
  while ( count > 0 )
  {
    Serial.write( *rover );
    ++rover;
    --count;
  }
}

SendIt( &MyInt, sizeof(MyInt) );

That's so sad, I can't tell you.

Read this before posting a programming question

What code? What errors?

Not "things like". Copy and paste the errors.

Function overloading is really just syntactic sugar for having multiple functions with the same name but different formal parameter lists. Name mangling behind the scenes ensures the linker can tell them apart, but they are all really completely different functions, of course.

If you really want just a single function, you could consider passing a void pointer to your function that holds the address of your variable/array/structure. You would have to pass a second argument as well to tell the function how many bytes the variable/array/structure holds. Defining a macro using sizeof() might be a neat solution for passing the second argument automatically.

Less coding and less flash memory than overloading.

Edit: Oops, just saw Coding Badly already did this. Must read more carefully before posting next time!

Please don't. Passing void basically defeats type checking. And then all the extra code to work out what type it has received will negate any savings of only having one function.

You now have one complex function that isn't type safe, rather than two simple functions which are.

Yes. That's the point.

The point is, you don't want to defeat type checking. Why do you think compiler-writers built that in?

That's so sad, I can't tell you.

Apologies, Nick. Those were actually the errors I got when I tried to compile my sketch with the EEPROMWriteAnything function in it. Word for word, copied and pasted. I just didn't make it clear. Sorry. Just finished a night shift.

So, which approach should I use? Passing a void pointer or writing multiple functions?

Chris

Multiple functions. If you have problems post your code.

However I don't have any objections to templates, which, in effect, produce multiple functions.

How do templates work? I have tried googleing but I can't seem to find a nice concise guide.

Yes. Sometimes you do.

Equally, why do you think they built in void pointer?

Type checking is very useful, a great invention. Sometimes however, it is nice to be able to side-step it if it gets in your way. C allows that.

EEPROMWriteAnything uses templates. Here:

#include <Arduino.h>  // for type definitions
#include <EEPROM.h>

template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
    const byte* p = (const byte*)(const void*)&value;
    unsigned int i;
    for (i = 0; i < sizeof(value); i++)
	    EEPROM.write(ee++, *p++);
    return i;
}

The templated type T is used to write to EEPROM.

pico:
Type checking is very useful, a great invention. Sometimes however, it is nice to be able to side-step it if it gets in your way. C allows that.

If you buy a gun, you can shoot yourself in the foot. If you want to.

I tried to compile a sketch including the code you posted and I get the following errors:

sketch_nov01a:2: error: expected ',' or '...' before '&' token
sketch_nov01a:2: error: ISO C++ forbids declaration of 'T' with no type

Using Arduino 1.0.1 on a Mac

True. It really comes down to whether or not you have the skill to handle the gun. You have to know the limits of your competence.

So I guess you never do any assembly language programming at all then, huh? How dangerous is that? No type checking at all. Every line of code a virtual death trap. :roll_eyes:

pico:
True. It really comes down to whether or not you have the skill to handle the gun. You have to know the limits of your competence.

Wow. Well this could always be settled with a duel. Handbags at dawn perhaps?
However, in the mean time.... why won't my code work? =(

Well whist you guys were fighting I tried this and it seems to work. Thanks

template <class T> void sendAnything(const T& value)
{
    const byte* p = (const byte*)(const void*)&value;
    unsigned int i;
    for (i = 0; i < sizeof(value); i++) {
      if (*p == 0x7E || *p == 0x7D) { //byte stuffing
        Serial.write(0x7D);
        Serial.write(*p++ ^ 0x20);
      } else {
        Serial.write(*p++);
      }
    }
}

Just one other quick question:
How might I modify the above code to send the bytes MSB first?