我想编写一个函数,将数组的json表示反序列化为std :: vector。我正在使用的json库是Facebook愚蠢的库的一部分。我想实现如下的一些事情,但遗憾的是它不起作用:
template<typename T>
static bool deserializeHelper(std::string fieldName, vector< T >& structField, const folly::dynamic& jsonObj) {
if(auto* jsonField = jsonObj.get_ptr(fieldName)){
if(jsonField->isArray()) {
for(auto& elem : *jsonField) {
if(elem.isInt()) {
structField.push_back(elem.asInt());
} else if(elem.isString()){
structField.push_back(elem.asString());
} else if(elem.isDouble()) {
structField.push_back(elem.asDouble());
} else if(elem.isBool()) {
structField.push_back(elem.asBool());
} else return false;
}
} else return false;
}
return true;
}
在上面的代码中,jsonField是数组字段的表示。所以代码只是尝试遍历数组;然后为每个元素;它将尝试推回到通用矢量:矢量。问题是代码无法编译,因为它会抱怨它无法从std :: string转换为int;当T = int;
我不知道如何在不需要实现4方法重载函数的情况下编写类似的泛型函数。 static bool deserializeHelper(std :: string fieldName,vector&lt; int&gt;&amp; structField,const folly :: dynamic&amp; jsonObj)....
感谢。
答案 0 :(得分:0)
似乎代码如下所示。我只是想知道是否有任何瓶颈,开销或以下工作正常:
template<typename T>
static bool deserializeHelper(std::string fieldName, vector<T>& structField, const folly::dynamic& jsonObj) {
if(auto* jsonField = jsonObj.get_ptr(fieldName)){
if(jsonField->isArray()) {
for(auto& elem : *jsonField) {
if(elem.isInt()) {
int tmp = elem.getInt();
structField.push_back(*(static_cast<T*>(static_cast<void*>(&tmp))));
} else if(elem.isString()){
std::string tmp = elem.getString().toStdString();
structField.push_back(*(static_cast<T*>(static_cast<void*>(&tmp))));
} else if(elem.isDouble()) {
double tmp = elem.getDouble();
structField.push_back(*(static_cast<T*>(static_cast<void*>(&tmp))));
} else if(elem.isBool()) {
bool tmp = elem.getBool();
structField.push_back(*(static_cast<T*>(static_cast<void*>(&tmp))));
} else return false;
}
} else return false;
}
return true;
}
基本上,在从void *到T *进行另一次转换之前,它会首先尝试转换为void *。我想知道是否有什么可以改进。
感谢。
答案 1 :(得分:0)
这两种类型安全的方法是:
T
语句中测试if
。看起来像这样:
#include <type_traits>
template<typename T>
static bool deserializeHelper(std::string fieldName, vector< T >& structField, const folly::dynamic& jsonObj) {
if(auto* jsonField = jsonObj.get_ptr(fieldName)){
if(jsonField->isArray()) {
for(auto& elem : *jsonField) {
if(std::is_same<T, bool>::value) {
structField.push_back(elem.asBool());
} else if(std::is_convertible<int64_t, T>::value) {
structField.push_back(elem.asInt());
} else if(std::is_convertible<std::string, T>::value){
structField.push_back(elem.asString());
} else if(std::is_convertible<double, T>::value) {
structField.push_back(elem.asDouble());
} else return false;
}
} else return false;
}
return true;
}
所有这些if
都将被静态评估,因此编译后的代码与只有used-branch一样有效。