91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++中類結構體與json如何相互轉換

發布時間:2021-09-30 10:43:55 來源:億速云 閱讀:163 作者:小新 欄目:開發技術

這篇文章給大家分享的是有關C++中類結構體與json如何相互轉換的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

1. 背景與需求

之前寫C#的時候,解析json字符串一般使用的是開源的類庫Newtonsoft.Json,方法十分簡潔,比如:

class Project
{
    public string Input { get; set; }
    public string Output { get; set; }
}
JavaScriptSerializer serializer = new JavaScriptSerializer();
Project test = serializer.Deserialize<Project>(@"{"Input":"1","Output":"2"}");

一行代碼就能將json字符串轉為相應的類對象。

最近寫C++需要處理一下json數據,于是上github找了很多很強大的開源庫,像jsoncpprapidjsonjson,基本上都滿足了開發需求,但想要做成像寫C#那樣子就要做二次開發。于是有了自己寫一個簡單的json轉類 | 結構體的工具的想法(開源地址)。

需求如下:

  • 只有頭文件,方便使用

  • 最多三行代碼解決轉換

  • 支持類|結構體 與 json的相互轉換

  • 支持多種基本數據類型,如intfloatstringbool

  • 支持STL基本類型,如vectorlistmap<string,T>等

  • 支持嵌套關系

  • 支持成員重命名,比方說json中的關鍵字是name,成員命名可寫成Name或其他。

2. 最終使用的樣例代碼

class Student
{
public:
    string Name;
    int Age;

    AIGC_JSON_HELPER(Name, Age)//成員注冊
    AIGC_JSON_HELPER_RENAME("name","age")//成員重命名,不需要可以刪除這條
};

int main()
{
    //json轉類對象
    Student person;
    JsonHelper::JsonToObject(person, R"({"name":"XiaoMing", "age":15})");
 //類對象轉json
    string jsonStr;
    JsonHelper::ObjectToJson(person, jsonStr);
    return 0;
}

3. 實現方法

因為剛好rapidjson只需要頭文件就可以使用,所以選擇了rapidjson作為基礎庫,進行二次開發。

3.1 基礎類型的轉換

作為最底層的接口,只需要進行一個賦值的操作即可,后續如果想要增加一些其他類型支持,添加起來也比較方便。

static bool JsonToObject(int &obj, rapidjson::Value &jsonValue)
{
    if (jsonValue.IsNull() || !jsonValue.IsInt())
        return false;
    obj = jsonValue.GetInt();
    return true;
}

static bool JsonToObject(unsigned int &obj, rapidjson::Value &jsonValue)
{
    if (jsonValue.IsNull() || !jsonValue.IsUint())
        return false;
    obj = jsonValue.GetUint();
    return true;
}

static bool JsonToObject(int64_t &obj, rapidjson::Value &jsonValue)
{
    if (jsonValue.IsNull() || !jsonValue.IsInt64())
        return false;
    obj = jsonValue.GetInt64();
    return true;
}

//其他類型... ...

3.2 類成員注冊

這里使用宏定義方式 + 可變參數模板的方式來實現,即可依次對注冊的成員進行賦值

template <typename TYPE, typename... TYPES>
static bool WriteMembers(std::vector<std::string> &names, int index, rapidjson::Value &jsonValue, TYPE &arg, TYPES &... args)
{
    if (!WriteMembers(names, index, jsonValue, arg))
        return false;
    return WriteMembers(names, ++index, jsonValue, args...);
}

template <typename TYPE>
static bool WriteMembers(std::vector<std::string> &names, int index, rapidjson::Value &jsonValue, TYPE &arg)
{
    const char *key = names[index].c_str();
    if (!jsonValue.HasMember(key))
        return true;

    if (!JsonToObject(arg, jsonValue[key]))
        return false;
    return true;
}
#define AIGC_JSON_HELPER(...)  \
bool AIGC_CONVER_JSON_TO_OBJECT(rapidjson::Value &jsonValue, std::vector<std::string> &names) \
{     \
    if (names.size() <= 0)  \
        names = aigc::JsonHelper::GetMembersNames(#__VA_ARGS__); \
    return aigc::JsonHelper::WriteMembers(names, 0, jsonValue, __VA_ARGS__); \
}

3.3 自定義類的轉換

自定義類由于并不清楚外界使用時,是否有按規定添加好成員注冊接口,所以這里采用enable_if的方式來嘗試調用,編譯的時候也就不會報錯。

template <bool, class TYPE = void>
struct enable_if
{
};

template <class TYPE>
struct enable_if<true, TYPE>
{
    typedef TYPE type;
};

template <typename T>
struct HasConverFunction
{
    template <typename TT> static char func(decltype(&TT::AIGC_CONVER_JSON_TO_OBJECT));
    template <typename TT> static int func(...);
    const static bool has = (sizeof(func<T>(NULL)) == sizeof(char));
};

template <typename T, typename enable_if<HasConverFunction<T>::has, int>::type = 0>
static inline bool JsonToObject(T &obj, rapidjson::Value &jsonValue)
{
    std::vector<std::string> names = LoadRenameArray(obj);
    return obj.AIGC_CONVER_JSON_TO_OBJECT(jsonValue, names);
}

template <typename T, typename enable_if<!HasConverFunction<T>::has, int>::type = 0>
static inline bool JsonToObject(T &obj, rapidjson::Value &jsonValue)
{
    return false;
}

3.4 外部調用接口

/**
 * @brief conver json string to class | struct
 * @param obj : class or struct
 * @param jsonStr : json string 
 */
template <typename T>
static inline bool JsonToObject(T &obj, const std::string &jsonStr)
{
    rapidjson::Document root;
    root.Parse(jsonStr.c_str());
    if (root.IsNull())
        return false;

    return JsonToObject(obj, root);
}

最核心的部分也就上面的幾個模塊,其他的都是一些瑣碎的增加類型支持等操作。

感謝各位的閱讀!關于“C++中類結構體與json如何相互轉換”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

c++
AI

牙克石市| 正宁县| 宜宾市| 安溪县| 洛宁县| 马尔康县| 洪泽县| 苍梧县| 隆昌县| 额尔古纳市| 肇源县| 霍邱县| 扶沟县| 南江县| 宣城市| 喀喇沁旗| 怀仁县| 彭阳县| 丹寨县| 星子县| 峨边| 淅川县| 耿马| 四会市| 河间市| 潼南县| 凌海市| 克拉玛依市| 台江县| 昌平区| 晋江市| 郸城县| 黎平县| 中西区| 古交市| 平潭县| 翁源县| 渝北区| 许昌县| 许昌市| 常山县|