C++11 json反序列化的运行时模板函数类型转换

C++11 json反序列化的运行时模板函数类型转换,c++11,casting,json-deserialization,template-function,folly,C++11,Casting,Json Deserialization,Template Function,Folly,我想编写一个函数,将数组的json表示反序列化为std::vector。我使用的json库是Facebook的folly库的一部分。我希望实现以下目标,但不幸的是,它不起作用: template<typename T> static bool deserializeHelper(std::string fieldName, vector< T >& structField, const folly::dynamic& jsonObj) {

我想编写一个函数,将数组的json表示反序列化为std::vector。我使用的json库是Facebook的folly库的一部分。我希望实现以下目标,但不幸的是,它不起作用:

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;
}
模板
静态bool反序列化帮助程序(std::string fieldName,vector&structField,const folly::dynamic&jsonObj){
if(auto*jsonField=jsonObj.get_ptr(fieldName)){
如果(jsonField->isArray()){
用于(自动和电气:*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());
}否则返回false;
}
}否则返回false;
}
返回true;
}
在上面的代码中,jsonField是数组字段的表示形式。因此,代码只是尝试在数组中循环;然后针对每个元素;它将尝试推回通用向量:vector。问题是代码无法编译,因为它会抱怨无法从std::string转换为int;当T=int时

我不知道如何编写这样的通用函数,而不需要实现4个方法重载函数。 静态bool反序列化帮助程序(std::string fieldName,vector&structField,const folly::dynamic&jsonObj)


谢谢。

下面的作品中的代码似乎是这样的。我只是想知道是否存在任何瓶颈、开销或以下工作正常:

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;
}
模板
静态bool反序列化helper(std::string字段名、vector和structField、const folly::dynamic和jsonObj){
if(auto*jsonField=jsonObj.get_ptr(fieldName)){
如果(jsonField->isArray()){
用于(自动和电气:*jsonField){
if(elem.isInt()){
int tmp=elem.getInt();
structField.push_back(*(static_cast(static_cast)(&tmp)));
}else if(elem.isString()){
std::string tmp=elem.getString().toStdString();
structField.push_back(*(static_cast(static_cast)(&tmp)));
}else if(elem.isDouble()){
double tmp=elem.getDouble();
structField.push_back(*(static_cast(static_cast)(&tmp)));
}else if(elem.isBool()){
bool tmp=elem.getBool();
structField.push_back(*(static_cast(static_cast)(&tmp)));
}否则返回false;
}
}否则返回false;
}
返回true;
}
基本上,在从void*到T*进行另一次铸造之前,它将首先尝试铸造到void*。我想知道是否有什么可以改进的


谢谢。

下面的作品中的代码似乎是这样的。我只是想知道是否存在任何瓶颈、开销或以下工作正常:

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;
}
模板
静态bool反序列化helper(std::string字段名、vector和structField、const folly::dynamic和jsonObj){
if(auto*jsonField=jsonObj.get_ptr(fieldName)){
如果(jsonField->isArray()){
用于(自动和电气:*jsonField){
if(elem.isInt()){
int tmp=elem.getInt();
structField.push_back(*(static_cast(static_cast)(&tmp)));
}else if(elem.isString()){
std::string tmp=elem.getString().toStdString();
structField.push_back(*(static_cast(static_cast)(&tmp)));
}else if(elem.isDouble()){
double tmp=elem.getDouble();
structField.push_back(*(static_cast(static_cast)(&tmp)));
}else if(elem.isBool()){
bool tmp=elem.getBool();
structField.push_back(*(static_cast(static_cast)(&tmp)));
}否则返回false;
}
}否则返回false;
}
返回true;
}
基本上,在从void*到T*进行另一次铸造之前,它将首先尝试铸造到void*。我想知道是否有什么可以改进的


谢谢。

两种类型安全的方法是:

  • 写4种方法,你已经拒绝了;及
  • if
    语句中测试
    T
可能看起来像这样:

#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;
}
#包括
模板
静态bool反序列化帮助程序(std::string fieldName,vector&structField,const folly::dynamic&jsonObj){
if(auto*jsonField=jsonObj.get_ptr(fieldName)){
如果(jsonField->isArray()){
用于(自动和电气:*jsonField){
if(std::is_same::value){
structField.push_back(elem.asBool());
}else if(标准::可转换::值){
structField.push_back(elem.asInt());
}else if(标准::可转换::值){
structField.push_back(elem.asString());
}else if(标准::可转换::值){
structField.push_back(elem.asDouble());
}否则返回false;
}
}否则返回false;
}
返回true;
}

所有这些
if
s都将静态计算,因此编译后的代码的效率与只有使用过的分支的效率一样。

实现这一点的两种类型安全方法是:

  • 写4种方法,你已经拒绝了;及
  • if
    语句中测试
    T
可能看起来像这样:

#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;
}
#包括
模板
静态bool反序列化帮助程序(std::string fieldName,vector&structField,const folly::dynamic&jsonObj){
如果(自动*jsonField=jsonO