Replacing deprecated 'containsKey' with is<T> in a template fails to compile
MartinMueller2003 opened this issue · 3 comments
Description
Updating a set of templates that have been working for a long time, fails.
Same code placed directly in a 'cpp' file works properly.
Troubleshooter's report
- The program uses ArduinoJson 7
- The issue happens at compile time
- The error is not in the list
Environment
- Microcontroller: ESP8266, ESP32 (multiple variants)
- Core/Framework: platform = https://github.com/platformio/platform-espressif32 # 6.8.1 ; uses esp-idf 5.1
- IDE: PlatformIO - Multiple versions tested.
Reproduction code
template <typename T, typename J, typename K>
bool setFromJSON (T& OutValue, J& Json, K Key)
{
bool HasBeenModified = false;
if (Json[Key].is<T>())
{
T temp = Json[Key];
if (temp != OutValue)
{
OutValue = temp;
HasBeenModified = true;
}
}
else
{
DEBUG_V(String("Could not find field '") + Key + "' in the json record");
}
return HasBeenModified;
}; // setFromJSON
Remarks
Usage:
ConfigChanged |= setFromJSON (config.id, JsonDeviceConfig, CN_id);
String, JsonObject, const char *
Compiler output:
ESPixelStick/src/input/../ESPixelStick.h: In function 'bool setFromJSON(T&, J&, K)':
ESPixelStick/src/input/../ESPixelStick.h:113:23: error: expected primary-expression before '>' token
if (Json[Key].is())
^
ESPixelStick/src/input/../ESPixelStick.h:113:25: error: expected primary-expression before ')' token
if (Json[Key].is())
Since J
is a template parameter, the compiler cannot know that J
is supposed to be a class that supports a template member function is<T>()
, so it incorrectly assumes that you wanted to use the <
operator on a member variable, like so:
Json[Key].is < T > () // error: expected primary-expression before '>' token
That's why you get this curious error: the compiler expected T
to be a primary expression, not a type.
To fix this, you must convince the compiler that the <
sign is not a comparison operator but the beginning of a template argument list. This is done by replacing .
with .template
like so:
if (Json[Key].template is<T>())
Note that you wouldn't have had this error if you had used JsonVariant
or JsonObject
for the type of the Json
argument instead of a template parameter.
Best regards,
Benoit
Thank You. That works
I did not specify JsonVariant or JsonObject because both of them are passed as the Json data be different callers. Just using the power of templates :)
You're welcome, @MartinMueller2003.
Thank you for using ArduinoJson!
Don't forget to cast a star to support the project 😉