boost::static_visitor/仿json类型

boost::static_visitor 是 Boost.Variant 库中的一个辅助类,用于定义 访问者(visitor),以便在 boost::variant 类型上执行 静态多态操作。
它允许你安全地对变体(variant)中存储的不同类型进行不同的处理,避免了复杂的 if-else 或类型判断。
#include <boost/variant.hpp>
#include <iostream>
#include <string>
2. 定义 variant 类型
typedef boost::variant<int, double, std::string> my_variant;

1.必须覆盖所有类型:如果你的 variant 包含 int, double, string,那么 static_visitor 的 operator() 必须实现这三种类型的重载,否则编译失败。
2.性能高:所有分发在编译期完成,无运行时开销。
3.类型安全:比 dynamic_cast 或手动类型检查更安全。
//定义访问者:打印访问者(PrintVisitor)
//这个访问者将根据 variant 中的实际类型输出内容。

struct PrintVisitor : public boost::static_visitor<void> {
    void operator()(int i) const {
        std::cout << "Integer: " << i << std::endl;
    }

    void operator()(double d) const {
        std::cout << "Double: " << d << std::endl;
    }

    void operator()(const std::string& s) const {
        std::cout << "String: " << s << std::endl;
    }
};
int main() {
    std::vector<my_variant> data = {42, 3.14, std::string("Hello"), 100, 2.718};

    std::cout << "打印所有 variant 值:\n";
    PrintVisitor print_vis;
    for (const auto& var : data) {
        boost::apply_visitor(print_vis, var);
    }

    return 0;
}
boost::variant 实现 JSON 类型
实现一个 json_value 类型,能表示:
  null
  bool
  int / double
  std::string
  std::vector<json_value> (数组)
  std::map<std::string, json_value> (对象)
#include <boost/variant.hpp>
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <memory>

struct json_array : std::vector<json_value> {
    using vector_type = std::vector<json_value>;
    using vector_type::vector_type; // 继承构造函数

    json_array() = default;
    json_array(vector_type v) : vector_type(std::move(v)) {}
};

struct json_object : std::map<std::string, json_value> {
    using map_type = std::map<std::string, json_value>;
    using map_type::map_type;

    json_object() = default;
    json_object(map_type m) : map_type(std::move(m)) {}
};

// 定义 JSON 基本类型 variant
// 使用 recursive_variant 允许嵌套自身
typedef boost::recursive_variant<
    std::nullptr_t,           // null
    bool,                     // true / false
    int,                      // 整数
    double,                   // 浮点数
    std::string,              // 字符串
    boost::recursive_wrapper<json_array>,   // 数组
    boost::recursive_wrapper<json_object>   // 对象
>::type json_value;
//  定义打印访问者(Pretty Printer)
struct json_printer : public boost::static_visitor<void> {
    std::ostream* os;
    int indent_level;

    json_printer(std::ostream* o, int level = 0) : os(o), indent_level(level) {}

    void print_indent() const {
        for (int i = 0; i < indent_level; ++i) *os << "  ";
    }

    void operator()(std::nullptr_t) const {
        *os << "null";
    }

    void operator()(bool b) const {
        *os << (b ? "true" : "false");
    }

    void operator()(int i) const {
        *os << i;
    }

    void operator()(double d) const {
        *os << d;
    }

    void operator()(const std::string& s) const {
        *os << '"' << s << '"';
    }

    void operator()(const json_array& arr) const {
        *os << "[\n";
        for (size_t i = 0; i < arr.size(); ++i) {
            if (i > 0) *os << ",\n";
            print_indent();
            *os << "  ";
            boost::apply_visitor(json_printer(os, indent_level + 1), arr[i]);
        }
        *os << "\n";
        print_indent();
        *os << "]";
    }

    void operator()(const json_object& obj) const {
        *os << "{\n";
        auto it = obj.begin();
        for (size_t i = 0; it != obj.end(); ++it, ++i) {
            if (i > 0) *os << ",\n";
            print_indent();
            *os << "  \"" << it->first << "\": ";
            boost::apply_visitor(json_printer(os, indent_level + 1), it->second);
        }
        *os << "\n";
        print_indent();
        *os << "}";
    }
};

//  封装:输出操作符
std::ostream& operator<<(std::ostream& os, const json_value& val) {
    json_printer printer(&os);
    boost::apply_visitor(printer, val);
    return os;
}
struct type_name_visitor : public boost::static_visitor<std::string> {
    std::string operator()(std::nullptr_t) const { return "null"; }
    std::string operator()(bool) const { return "boolean"; }
    std::string operator()(int) const { return "integer"; }
    std::string operator()(double) const { return "number"; }
    std::string operator()(const std::string&) const { return "string"; }
    std::string operator()(const json_array&) const { return "array"; }
    std::string operator()(const json_object&) const { return "object"; }
};

std::string type_name(const json_value& v) {
    return boost::apply_visitor(type_name_visitor(), v);
}
int main() {
    // 构造一个复杂的 JSON 对象
    json_object person{
        {"name", std::string("Alice")},
        {"age", 30},
        {"is_student", false},
        {"grade", nullptr}, // null
        {"scores", json_array{95, 87.5, 90}},
        {"address", json_object{
            {"city", "Beijing"},
            {"zip", 100000}
        }}
    };

    json_value data = person;

    std::cout << "构造的 JSON 数据:\n";
    std::cout << data << std::endl;

    return 0;
}
posted @ 2019-06-24 22:13  osbreak  阅读(624)  评论(0)    收藏  举报