字符串与整数模板冲突及json-glib生成JSON的字符处理问题
解决json-glib生成多类型JSON时的字符串处理问题
看起来你在使用json-glib构建包含多类型value字段的JSON结构时,卡在了std::string的c_str()和char*类型的处理上。我来帮你梳理下完整的解决方案,同时完善你现有的类型分支逻辑:
核心问题分析
你现有的代码已经覆盖了整数和布尔类型,但缺少字符串(std::string/const char*/char*)和浮点数的处理逻辑。其中字符串类型的关键在于:
- json-glib的
json_builder_add_string_value接受const gchar*(本质等价于const char*)作为参数 - std::string的
c_str()返回临时的const char*,但json-glib会内部复制字符串内容,只要调用API时字符串对象未被销毁/修改就不会有悬空指针问题 - char需要强转为const char才能匹配API参数类型
完整的泛型处理代码
下面是一个覆盖所有你提到的类型的泛型函数,用C++17的if constexpr实现编译期类型分支,避免运行时开销:
#include <json-glib/json-glib.h> #include <type_traits> #include <string> // 泛型函数:向JsonBuilder添加对应类型的value bool add_json_value(JsonBuilder* builder, const auto& tagValue) { using T = std::decay_t<decltype(tagValue)>; // 处理布尔类型 if constexpr (std::is_same_v<T, bool>) { if (!json_builder_add_boolean_value(builder, tagValue)) { // 这里可以添加你的错误处理逻辑,比如设置返回信息 return false; } } // 处理整数类型(排除布尔) else if constexpr (std::is_integral_v<T> && !std::is_same_v<T, bool>) { if (!json_builder_add_int_value(builder, static_cast<gint64>(tagValue))) { return false; } } // 处理浮点数类型 else if constexpr (std::is_floating_point_v<T>) { if (!json_builder_add_double_value(builder, static_cast<gdouble>(tagValue))) { return false; } } // 处理std::string类型 else if constexpr (std::is_same_v<T, std::string>) { // c_str()返回const char*,直接传入即可,json-glib会内部复制内容 if (!json_builder_add_string_value(builder, tagValue.c_str())) { return false; } } // 处理const char*类型 else if constexpr (std::is_same_v<T, const char*>) { if (!json_builder_add_string_value(builder, tagValue)) { return false; } } // 处理char*类型:强转为const char*匹配API参数 else if constexpr (std::is_same_v<T, char*>) { if (!json_builder_add_string_value(builder, static_cast<const char*>(tagValue))) { return false; } } // 不支持的类型分支 else { // 可以添加不支持类型的错误提示 return false; } return true; }
关键注意事项
c_str()的生命周期:只要在调用json_builder_add_string_value时,std::string对象还处于存活状态(未被销毁或修改),c_str()的指针就是有效的,无需担心悬空问题——因为json-glib会把字符串内容复制到内部结构中。- 类型匹配:char类型必须强转为const char,否则会触发编译错误(json-glib的API不接受非const的char*)。
- json-glib初始化:务必在程序启动时调用
json_init(),结束时调用json_cleanup(),否则API可能无法正常工作。
使用示例(构建完整的JSON对象)
int main() { // 初始化json-glib json_init(); JsonBuilder* builder = json_builder_new(); json_builder_begin_object(builder); // 添加id字段(固定为std::string类型) json_builder_set_member_name(builder, "id"); std::string user_id = "rest_api_001"; if (!add_json_value(builder, user_id)) { g_printerr("Failed to add id field\n"); goto cleanup; } // 测试添加字符串类型的value json_builder_set_member_name(builder, "value"); std::string str_value = "Hello JSON-GLib"; if (!add_json_value(builder, str_value)) { g_printerr("Failed to add string value\n"); goto cleanup; } // 你也可以测试其他类型: // json_builder_set_member_name(builder, "value"); // bool bool_val = true; // add_json_value(builder, bool_val); json_builder_end_object(builder); // 生成并打印JSON字符串 JsonNode* root = json_builder_get_root(builder); gchar* json_str = json_to_string(root, TRUE); g_print("Generated JSON:\n%s\n", json_str); cleanup: // 释放资源 if (json_str) g_free(json_str); if (root) json_node_unref(root); g_object_unref(builder); json_cleanup(); return 0; }
内容的提问来源于stack exchange,提问作者Dark Sorrow
相关产品推荐
相关产品推荐

