0

I'm trying to create a function that enters a key/value into a JSON file.

But, since value can be an int or char, I don't want to create 2 functions for each type.

Is there a way ?

void setValue(char *key, char* value){
        StaticJsonDocument<512> tempJDOC;
        tempJDOC[key]=value;
}

EDIT1

#ifndef myJSON_h
#define myJSON_h

#include "Arduino.h"
#include <ArduinoJson.h>
#include "FS.h"


class myJSON
{
private:
bool _useSerial=false;
char _filename[30];

public:
char *ver="myJSON_v1.1";
myJSON(char *filename, bool useserial=false);

bool file_exists();
bool file_remove();
bool format ();
bool FS_ok();

void saveJSON2file(JsonDocument& _doc);
void readJSON_file(JsonDocument& _doc);

void printJSON(JsonDocument& _doc);
void PrettyprintJSON(JsonDocument& _doc);

const char *getValue (char *key);

template <class T>
void setValue(const char *key, T value);
//void setValue(const char *key, char *value);

};
#endif

EDIT2

#ifndef myJSON_h
#define myJSON_h

#include "Arduino.h"
#include <ArduinoJson.h>
#include "FS.h"

#define LOG_LENGTH 4
#define DOC_SIZE 512

template <class T> // . <---- line added
class myJSON
{
private:
bool _useSerial=false;
char _filename[30];

public:
char *ver="myJSON_v1.1";
myJSON(char *filename, bool useserial=false);

bool file_exists();
bool file_remove();
bool format ();
bool FS_ok();

void saveJSON2file(JsonDocument& _doc);
void readJSON_file(JsonDocument& _doc);

void printJSON(JsonDocument& _doc);
void PrettyprintJSON(JsonDocument& _doc);

const char *getValue (const char *key);
void removeValue(const char *key);
// void setValue(const char *key, char *value); <--- comment out
void updateArray(char* array_key, int val);
void printFile();
void setValue(const char *key, T value); <---- Added

};
#endif

and in .cpp file :

void myJSON::setValue(const char *key, T value){
        StaticJsonDocument<512> tempJDOC;
        myJSON::readJSON_file(tempJDOC);
        tempJDOC[key]=value;
        myJSON::saveJSON2file(tempJDOC);
        myJSON::PrettyprintJSON(tempJDOC);
}
7
  • how will the code that calls the function decide if it's setting a number or a string? Commented Apr 27, 2019 at 1:44
  • Um... The title and the text of your question refers to char parameter. The code seems to suggest that you are actually talking about char * parameter. So, what is it? char or char *? These are two very different things. You have to edit your question and clarify that. Commented Apr 30, 2019 at 19:10
  • @AnT - you are right, but it is commented out at this point since as juraj and edgar suggested to use template - so I don't need to use int nor char
    – guyd
    Commented Apr 30, 2019 at 19:14
  • If you needed to pass either int or char you wouldn't need to do anything at all. You don't need any "templates". Just one int version of the function by itself would cover all cases, including char, since in C and C++ char is just a small integer type. So, again, why are you asking this question? What is the problem with char that triggered it? Again, the code you provided implies that you need char * (or, better, const char *). Not char, but const char *. You need to reflect it in your question, since currently neither the question not the accepted answer make sense. Commented Apr 30, 2019 at 19:16
  • And when you use template, you are using int or const char *, albeit you are doing it implicitly. The compiler does it for you. But again, it is a matter of int and const char *, not a matter of int and char as you stated in your question. char is completely irrelevant here. Commented Apr 30, 2019 at 19:21

2 Answers 2

2

In C++ you can create a template function. (The ArduinoJson [] operator is a template too.)

#include <ArduinoJson.h>

StaticJsonDocument<512> tempJDOC;

template <typename T>
void setValue(const char *key, T value){
  tempJDOC[key] = value;
}

void setup() {
  Serial.begin(115200);

  setValue("a", 5);
  setValue("b", "xyz");

  serializeJson(tempJDOC, Serial);
}

void loop() {
}

the compiler will create function based on this template for every different type you use as second parameter in your sketch

10
  • When trying to take such function and put it inside a library ( using template as noted here ), i get an error. how can it be done?
    – guyd
    Commented Apr 29, 2019 at 20:22
  • by "put it inside a library", you mean using it as class's method?
    – Juraj
    Commented Apr 30, 2019 at 4:54
  • a method that uses template inside a class
    – guyd
    Commented Apr 30, 2019 at 5:42
  • add the code of the class to the Question. is it a class with separate .h and .cpp files? do you have the template<> part of function declaration in .h too?
    – Juraj
    Commented Apr 30, 2019 at 7:23
  • pasted .h file inside my Q
    – guyd
    Commented Apr 30, 2019 at 18:54
1

The short answer is “no, it's not possible”. You will have to use two different functions. These two functions can share the same name, using function overloading. You can even have the compiler write these functions for you, based on a template you provide, as shown in Juraj's answer. These language features help provide the illusion of there being a single function. But it's just an illusion, albeit a useful one that helps with program readability. At the fundamental level, you still have two different functions.

4
  • Edgar - thank you for explaining and usefull link. But I do not understand how Juraj's answer ( using template ) creates/ duplicates the function for other types
    – guyd
    Commented Apr 27, 2019 at 20:22
  • 1
    @Guy.D: Do a search for “C++ templates”. In short, every time you call setValue() with a new value type, the compiler creates a new version of the setValue() function suitable for that specific type. Commented Apr 27, 2019 at 20:26
  • 1
    I have in my answer: "the compiler will create function based on this template for every different type you use as second parameter in your sketch"
    – Juraj
    Commented Apr 30, 2019 at 13:42
  • @EdgarBonet I use you link to try to implement this function inside a lib I make ( called myJSON, as you can see in edit 1 and edit 2 ). I'll appreciate your help once more
    – guyd
    Commented May 1, 2019 at 6:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.