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;
}