The question is a bit confusing so let me clarify by explaining my predicament.
I'm using nlohman::json
and trying to do conversions between nlohman::json
value types and QString
s from QT 5.8. In order to do those conversions I came to the conclusion that I would need to use the json libraries json::is_typexxx
for json value types. This ended up looking like this:
QString convertQString(const json &json_in) {
if (json_in.is_number_integer()) {
return //QString integer conversion
} else if (json_in.is_number_float()) {
return //QString float conversion
} else if (json_in.is_string()) {
return //QString std::string conversion
} else if (json_in.is_boolean()) {
return //QString bool conversion
}
return // QString no type found default
}
I soon realized that I would need to convert QStrings back into values for nlohman::json
, in doing so I started to write the following function
void convertJson(.../**notimportant**/... json& json_out){
... /**more stuff here**/
if (json_out.is_number_integer()) {
...
} else if (json_out.is_number_float()) {
...
} else if (json_out.is_string()) {
...
} else if (json_out.is_boolean()) {
...
}
...
}
and soon realized I was just writing the same logic for checking types. Naturally I thought this was an excellent oportunity to use the Template Method Pattern, and started writing the following classes:
template<typename T>
class JsonChoice {
protected:
T makechoice(const nlohmann::json &json_in);
virtual T ifinteger() = 0;
...// other functions that follow the "iftypexxx()" convention
};
template<typename T>
T JsonChoice::choice(const nlohmann::json &json_in) {
if (json_in.is_number_integer()) {
return ifinteger();
... //you get the pattern...
}
QStringConverter : public JsonChoice<QString>{
...
protected:
QString ifinteger();
... //etc
};
// friend define operator ()?
JsonConverter : public JsonChoice<nlohmann::json>{
...
protected:
nlohmann::json ifinteger();
... //etc
};
// friend define operator ()?
It was at this point that I realized I didn't need state in either of my Template Method Pattern functors. However most examples I've seen of this pattern implemented are made like so:
TMPFunctor = tmpfun(statevar);
...
So I was wary of not following convention here, but since I didn't need any state, it didn't seem like it was a good idea to force myself to have to create a variable every time I wanted to use what was essentially a function with internal logic switched out depending on the signature. I started wondering if I even should use functors to accomplish this task, as I could techinically template every part of the process to simply create one function as well. Is this an adequate solution to this problem, to create a functor class with all static members, use it as a functor?
According to this statically overloading () is a problem however and I'm not sure if I should just wrap another class function in another function like so to solve this issue:
QString convertQstring(const nlohmann::json &json_in){
return QStringConverter.makechoice(json_in);
}
or just template every part of the function (which sounds annoying and ugly to me) to generalize the choice switch ie:
template<typename returnval, typename integerfunctemplate, ...>
returnval convert( const nlohmann::json &json_in){
if (json_in.is_number_integer()) {
return integerfunctemplate();
...
}
Aucun commentaire:
Enregistrer un commentaire