#include <Arduino.h>
#include "PrintBin.h"
template <class T>
void PrintBin::printBinA(T data);
{
for (int b = (sizeof(data) * 8) - 1; b >= 0; b--)
{
if ((data & (1 << b)))
{
Serial.print(1);
}
else
{
Serial.print(0);
}
}
}
The test sketch
#include "PrintBin.h"
void setup()
{
Serial.begin(115200);
int var = 0b0101010110101010;
printBinA(var);
}
void loop()
{
}
The error
Arduino: 1.8.13 (Windows 10), Board: "Arduino Nano, ATmega328P"
C:\Users\Bob2\AppData\Local\Temp\arduino_modified_sketch_99622\printBin_build.ino: In function 'void setup()':
printBin_build:7:3: error: 'printBinA' was not declared in this scope
printBinA(var);
^~~~~~~~~
C:\Users\Bob2\AppData\Local\Temp\arduino_modified_sketch_99622\printBin_build.ino:7:3: note: suggested alternative: 'PrintBin'
printBinA(var);
^~~~~~~~~
PrintBin
exit status 1
'printBinA' was not declared in this scope
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
#include <Arduino.h>
#include "PrintBin.h"
void printBinA(T data)
{
for (int b = (sizeof(data) * 8) - 1; b >= 0; b--)
{
if ((data & (1 << b)))
{
Serial.print(1);
}
else
{
Serial.print(0);
}
}
}
the test sketch
#include "PrintBin.h"
void setup()
{
Serial.begin(115200);
int var = 0b0101010110101010;
printBinA(var);
}
void loop()
{
}
the error message
Arduino: 1.8.13 (Windows 10), Board: "Arduino Nano, ATmega328P"
PrintBin.cpp:4:16: error: variable or field 'printBinA' declared void
void printBinA(T data)
^
PrintBin.cpp:4:16: error: 'T' was not declared in this scope
exit status 1
variable or field 'printBinA' declared void
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
Ok, but I am trying to keep this simple and not have the need to create an instance of an object to use the PrintBin functions. If I simply put the template function in the .h file, like this
template <class T>
void printBinA(T data)
{
for (int b = (sizeof(data) * 8) - 1; b >= 0; b--)
{
if ((data & (1 << b)))
{
Serial.print(1);
}
else
{
Serial.print(0);
}
}
}
and remove the .cpp file I can call the function perfectly well just like a non template function, but with any integer data type. However, I have seen advice previously that this is bad practice and should not be done, so I was trying to do it the correct way
Thanks but I think that I will stick to the "put the functions (there are more in the actual library) in the .h file" solution to avoid complications when calling them
Are there any real gotchas if I do this, bearing in mind it is only for my personal debugging that I am doing this ?
the template is a recipe, not a cake. there is no code generated for template. code exists only for functions or classes generated from the template for specific set of template parameters. So the entire template function definition must be in .h to generate a specific function for parameter types in .ino or in some cpp
So, that breaks the "do not define functions in .h files" 'rule' which I have seen mentioned previously in the forum. I will stick with the single .h file approach as these template functions are just for my convenience
#include <PrintBin.h>
void setup()
{
Serial.begin(115200);
functions();
uint32_t var = 0b01010101101010100101010110101010;
Serial.print("printBin(var)\t");
printBin(var);
Serial.println("\nnewline from sketch");
Serial.print("printBinln(var)\t");
printBinln(var);
Serial.println("\nnewline from sketch");
Serial.print("printBinBytes(var)\t");
printBinBytes(var);
Serial.println("\nnewline from sketch");
Serial.print("printBinBytesln(var)\t");
printBinBytesln(var);
Serial.println("\nnewline from sketch");
}
void loop()
{
}
void functions()
{
Serial.println("NOTE : unlike Serial.print(var, BIN); thes functions print leading zeroes");
Serial.println();
Serial.println("printBin(var); any integer variable as a series of bits");
Serial.println("printBinln(var); any integer variable as a series of bits with a newline");
Serial.println("printBinBytes(var); any integer variable as a series of bits split into bytes");
Serial.println("printBin(var); any integer variable as a series of bits split into bytes with a newline");
Serial.println();
Serial.println("Examples");
Serial.println();
}
because it is not a function, but a template to generate functions. there will be so many functions created as may different types you use as template parameter.