一种单一的数据结构,用于从脚本中读取任意类型的变量,以便在运行时进行检索和编辑
A single data structure for reading in arbitrary type variables from a script, for retrieval and editing at runtime
我想为一些机器人软件存储任意参数数据。我将举一些例子来澄清我想做什么:
例如,我想存储变量"quadruped.gait.step_height=0.25"answers"quadrupped.gait_type="trot",这应该分解为类似的内容
variable_map["quadruped"]["gait"]["step_height"] = 0.25;
或
variable_map["quadruped"]["gait"]["gait_type"] = "trot";
我目前必须处理这种事情的代码(如果我知道变量的类型,它就可以正常工作):
std::map<std::string, void* > var_map;
template <class X>
void set_variable(std::string key, X var)
{
var_map[key] = &var;
}
template <class X>
X get_variable(std::string key)
{
return *reinterpret_cast<X*>(var_map[key]);
}
这就完成了将每个变量存储在中的看起来不那么干净的任务
variable_map["quadruped.gait.step_height"] = 0.25;
这感觉像是一种粗制滥造的方式来做我想做的事。我需要提前知道变量的类型:
set_variable<bool>("quadruped.PID.workspace.active",true);
bool workspace_active = get_variable<bool>("quadruped.PID.workspace.active");
理想情况下,我希望在启动时在XML读取器或某种脚本解析格式中处理这种类型的变量分配。
我觉得这是软件开发人员的共同需求,我忍不住觉得我正在重新发明解决这个问题的方法。有没有一段开源代码(最好有一个好的许可证),或者只是一种更简单的脚本阅读方式:
quadruped.gait.gait_timing = [ 0 0.5 0 0.5 ]
quadruped.gait.step_height = 0.25
quadruped.gait.gait_type = "trot"
quadruped.PID.workspace.active = 1
并将其存储为:
variable_map["quadruped"]["gait"]["gait_timing"] = (std::vector) % containing [ 0 0.5 0 0.5 ]
variable_map["quadruped"]["gait"]["step_height"] = (double) 0.25;
variable_map["quadruped"]["gait"]["gait_type"] = (std::string) "trot";
variable_map["quadruped"]["PID"]["workspace"]["active"] = (int) 1;
或者可能只是以任何方式存储它们,我可以在代码中按名称检索它们,比如在我之前的例子中:
bool workspace_active = get_variable<bool>("quadruped.PID.workspace.active");
谢谢你的帮助。如果你需要进一步澄清我提出的任何一点,我将密切关注这个问题。
您的问题确实是一个常见问题。因此,存在一种常见的解决方案,即存储任意类型的变量的boost::variant
。
优点是它基于您考虑的所有潜在类型构建变体类型(并作为模板参数提供):
typedef boost::variant< int, std::string, double> vtype;
这种方法可以避免常见的问题,比如令人讨厌的未对齐变量(例如参见这个SO问题)。它还启用了一些编译时类型检查,确保您不会意外使用未预见的类型。
vtype v1, v2;
v1 = "Hello";
v2 = 0.25;
cout << v1 << v2;
如果你知道存储在一个对象中的类型,你可以很容易地得到它:而不是像*reinterpret_cast<X*>
那样危险:boost::get<X>()
boost提供了一种访问机制,以优雅的方式提供足够的类型相关代码,用于处理变体对象。你会在这个答案开头的链接中找到一些不错的例子。
考虑使用Boost.PropertyTree,它实现了"层次"映射,还通过解析器从一些常见格式的文件中读取配置。默认情况下,它以std::string格式存储值,但使用boost::lexical_cast
来支持设置和获取其他类型的值。如果您愿意,您可以使用Boost.Any或Boost.Variant来存储值,但这将失去一些解析功能。
- c++类声明时,相同的例程,不同的成员变量类型
- 如何为 c++ 的不同变量类型的结构元素创建动态数组?
- 创建类似于布尔值的变量类型
- std::cin 从控制台获取两种不同的变量类型,'storing'以后使用第二种类型?
- 如何使用变量模板比较 C++ 17 中的变量类型?
- 是否有一个库可以检查C++中的变量类型?
- 与不同变量类型相比,用于变量的 Clang AST 匹配器
- 继承类中的 C++ 成员变量类型重写
- 如何在编译器时动态获取元组内的变量类型C++?
- 在C++中动态分配变量类型
- 用于浮点值的最佳变量类型
- 定义变量类型
- 错误 - 变量类型 "X" 是一个抽象类 - c++
- 在函数 (c++) 中分配变量类型和大小数组
- 具有容器变量类型的类模板
- 获取变量类型名称
- 沿枚举 c++ 返回变量类型
- 是否可以通过模板指定抽象类变量类型
- 什么是变量类型位(32)
- C++ 在知道变量类型之前使用自动定义的变量