Using DynamicJsonDocument in std::map<>

Hi there,

I'm trying to compile the following sketch for ESP8266 Generic Board.
Getting an error during compile time. Any ideas how to solve that?

The code should act somehow as an DynamicJsonDocument cache.
Accessing a parsed document by key.

Thanks in advance for your guidance.

Markus

#include <ArduinoJson.h>
#include <map>

void setup()
{
  
}

void loop()
{
  std::map<String, DynamicJsonDocument> jsonCache;
  DynamicJsonDocument json(256);
  jsonCache["key"] = json; // this line triggers the error
}

The whole error message is to huge. Just showing a snip of it.

Arduino: 1.8.12 (Mac OS X), Board: "Generic ESP8266 Module, 80 MHz, Flash, Legacy (new can return nullptr), All SSL ciphers (most compatible), dtr (aka nodemcu), 26 MHz, 40MHz, DOUT (compatible), 1MB (FS:64KB OTA:~470KB), 2, nonos-sdk 2.2.1+100 (190703), v2 Lower Memory, Disabled, None, Only Sketch, 115200"

In file included from /Users/innofriends/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/xtensa-lx106-elf/include/c++/4.8.2/functional:55:0,
                 from /Users/innofriends/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/xtensa-lx106-elf/include/c++/4.8.2/bits/stl_algo.h:66,
                 from /Users/innofriends/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/xtensa-lx106-elf/include/c++/4.8.2/algorithm:62,
                 from /Users/innofriends/Library/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/cores/esp8266/Arduino.h:237,
                 from sketch/F8JTS3KJ0COLXAN.ino.cpp:1:
/Users/innofriends/Downloads/F8JTS3KJ0COLXAN/F8JTS3KJ0COLXAN.ino:13:18:   required from here
/Users/innofriends/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/xtensa-lx106-elf/include/c++/4.8.2/tuple:1088:70: error: no matching function for call to 'ArduinoJson6150_0000010::BasicJsonDocument<ArduinoJson6150_0000010::DefaultAllocator>::BasicJsonDocument()'
         second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
                                                                      ^
/Users/innofriends/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/2.5.0-4-b40a506/xtensa-lx106-elf/include/c++/4.8.2/tuple:1088:70: note: candidates are:
In file included from /Users/innofriends/Documents/Arduino/libraries/ArduinoJson/src/ArduinoJson/Document/DynamicJsonDocument.hpp:7:0,
                 from /Users/innofriends/Documents/Arduino/libraries/ArduinoJson/src/ArduinoJson.hpp:21,
                 from /Users/innofriends/Documents/Arduino/libraries/ArduinoJson/src/ArduinoJson.h:9,
                 from /Users/innofriends/Downloads/F8JTS3KJ0COLXAN/F8JTS3KJ0COLXAN.ino:1:
/Users/innofriends/Documents/Arduino/libraries/ArduinoJson/src/ArduinoJson/Document/BasicJsonDocument.hpp:78:3: note: ArduinoJson6150_0000010::BasicJsonDocument<TAllocator>::BasicJsonDocument(ArduinoJson6150_0000010::VariantRef) [with TAllocator = ArduinoJson6150_0000010::DefaultAllocator]
   BasicJsonDocument(VariantRef src)
   ^
/Users/innofriends/Documents/Arduino/libraries/ArduinoJson/src/ArduinoJson/Document/BasicJsonDocument.hpp:78:3: note:   candidate expects 1 argument, 0 provided
/Users/innofriends/Documents/Arduino/libraries/ArduinoJson/src/ArduinoJson/Document/BasicJsonDocument.hpp:66:3: note: template<class T> ArduinoJson6150_0000010::BasicJsonDocument<TAllocator>::BasicJsonDocument(const T&, typename ArduinoJson6150_0000010::enable_if<(((((ArduinoJson6150_0000010::is_same<T, ArduinoJson6150_0000010::VariantRef>::value || ArduinoJson6150_0000010::is_same<T, ArduinoJson6150_0000010::VariantConstRef>::value) || ArduinoJson6150_0000010::is_same<T, ArduinoJson6150_0000010::ArrayRef>::value) || ArduinoJson6150_0000010::is_same<T, ArduinoJson6150_0000010::ArrayConstRef>::value) || ArduinoJson6150_0000010::is_same<T, ArduinoJson6150_0000010::ObjectRef>::value) || ArduinoJson6150_0000010::is_same<T, ArduinoJson6150_0000010::ObjectConstRef>::value)>::type*)
   BasicJsonDocument(
   ^

The error tells you that the DynamicJsonDocument class doesn't have a default constructor. Without a default constructor a class cannot be used as the value type of an associative array (map container in C++).

You have several options:

  • Build your own class that fulfills the requirements (which might contain DynamicJsonDocument instances)
  • Use pointers (attention, very difficult, not recommended)
  • Use indirection (map contains only indices into a simple array)

In every case you're responsible for the memory management. If done wrongly you're out of memory in no time.

Thanks for your reply.

Also thought about using smart pointers.
I already tried it with std::shared_ptr yesterday.
Had the same error with that.
Maybe i implement a class deriving from DynamicJsonDocument.
That could be a way to go.
I'll give it a try.

Fixed it implementing a derived class from DynamicJsonDocument.

class ConfigurationJson : public DynamicJsonDocument
{
public:
    ConfigurationJson() : DynamicJsonDocument(256)
    {
    }
};

@pylon: Thanks for your advice!