I maintain an Arduino library which uses the following code (simplified) to print results received by infrared.
unsigned long long decodedData; // for 8 and 16 bit cores it is unsigned long decodedData;
Print MySerial;
MySerial.print(decodedData, 16);
Most of the 32 bit arduino cores provide the function size_t Print::print(unsigned long long n, int base)
and compile without errors.
But there are 32 bit cores, which do not provide size_t Print::print(unsigned long long n, int base)
, they only provide size_t Print::print(unsigned long n, int base)
and there I get the expected compile time error
call of overloaded 'print(decodedData, int)' is ambiguous
.
I tried to understand Check if a class has a member function of a given signature but still have no clue.
I want to use
MySerial.print((uint32_t)(decodedData >> 32), 16);
MySerial.print((uint32_t)decodedData & 0xFFFFFFFF, 16);
in case the function size_t Print::print(unsigned long long n, int base)
is not provided.
I tried
template<typename T>
struct has_uint64_print {
template<typename U, size_t (U::*)(unsigned long long, int)> struct SFINAE {
};
template<typename U> static char test(SFINAE<U, &U::print>*);
template<typename U>
static int test(...);
static const bool has64BitPrint = sizeof(test<T>(nullptr)) == sizeof(char);
};
and this works (Thanks to Remy Lebeau) :-).
But this check does not work, since it still references the long long print function (update: and using if constexpr ()
-which is not available for all cores- does not help).
if(has_uint64_print<Print>::has64BitPrint){
MySerial.print(decodedData, 16);
} else {
MySerial.print((uint32_t)(decodedData >> 32), 16);
MySerial.print((uint32_t)decodedData & 0xFFFFFFFF, 16);
}
Is there any chance to avoid this compile error?
BTW. I do not want to substitute all occurences of the 64 bit print with the 2 32 bit prints, only for one seldom used and lazy implemented 32 bit core, since all mainsteam cores work well with the 64 bit print.