从 Boost 属性 树中提取 STL 映射
Extracting STL Map from Boost Property Tree
我知道 boost::property_tree::ptree
可能包含键值对,其中 'value' 可以是任何类型。现在我的问题是,现在我的 'value' 是一个 std::map
,当我尝试 pt.get<std::map<std::string, std::string>>
其中 pt
是一个 属性 树时,我得到一个编译时间错误。因此,我的问题是:
如何从 boost 属性 树中提取 STL 映射值?如果这不可能,是否有任何方法可以在 STL 映射和 boost 属性 树之间进行转换(这样 属性 树的每个节点都不是 STL 容器,而是一种简单的数据类型).
非常简单:
ptree pt;
std::map<std::string, ptree> m(pt.begin(), pt.end());
但是,请注意键不必是唯一的:
std::multimap<std::string, ptree> mm(pt.begin(), pt.end());
如果您想将所有值转换为 std::string
(假设它们都有一个字符串值):
std::map<std::string, std::string> dict;
for (auto& [k,v]: pt) {
dict.emplace(k, v.get_value<std::string>());
}
并排比较
#include <boost/property_tree/ptree.hpp>
#include <map>
#include <fmt/ranges.h>
using boost::property_tree::ptree;
template<> struct fmt::formatter<ptree> : fmt::formatter<std::string>
{
template<typename Ctx>
auto format(ptree const& pt, Ctx& ctx) {
return format_to(ctx.out(), "'{}'", pt.get_value<std::string>());
}
};
int main() {
ptree pt;
pt.put("keyA", "valueA-1");
pt.put("keyB", "valueB");
pt.put("keyC", "valueC");
pt.add("keyA", "valueA-2"); // not replacing same key
std::map<std::string, ptree> m(pt.begin(), pt.end());
std::multimap<std::string, ptree> mm(pt.begin(), pt.end());
std::map<std::string, std::string> dict;
for (auto& [k,v]: pt) {
dict.emplace(k, v.get_value<std::string>());
}
fmt::print(
"map:\n\t{}\n"
"multimap:\n\t{}\n"
"dict:\n\t{}\n",
fmt::join(m, "\n\t"),
fmt::join(mm, "\n\t"),
fmt::join(dict, "\n\t")
);
}
版画
map:
("keyA", 'valueA-1')
("keyB", 'valueB')
("keyC", 'valueC')
multimap:
("keyA", 'valueA-1')
("keyA", 'valueA-2')
("keyB", 'valueB')
("keyC", 'valueC')
dict:
("keyA", "valueA-1")
("keyB", "valueB")
("keyC", "valueC")
奖励:来自字符串字典的 Ptree
template <typename MapLike>
ptree ptree_from_map(MapLike const& m) {
ptree pt;
for (auto const& [k,v]: m) {
pt.add(k, v);
}
return pt;
}
我知道 boost::property_tree::ptree
可能包含键值对,其中 'value' 可以是任何类型。现在我的问题是,现在我的 'value' 是一个 std::map
,当我尝试 pt.get<std::map<std::string, std::string>>
其中 pt
是一个 属性 树时,我得到一个编译时间错误。因此,我的问题是:
如何从 boost 属性 树中提取 STL 映射值?如果这不可能,是否有任何方法可以在 STL 映射和 boost 属性 树之间进行转换(这样 属性 树的每个节点都不是 STL 容器,而是一种简单的数据类型).
非常简单:
ptree pt;
std::map<std::string, ptree> m(pt.begin(), pt.end());
但是,请注意键不必是唯一的:
std::multimap<std::string, ptree> mm(pt.begin(), pt.end());
如果您想将所有值转换为 std::string
(假设它们都有一个字符串值):
std::map<std::string, std::string> dict;
for (auto& [k,v]: pt) {
dict.emplace(k, v.get_value<std::string>());
}
并排比较
#include <boost/property_tree/ptree.hpp>
#include <map>
#include <fmt/ranges.h>
using boost::property_tree::ptree;
template<> struct fmt::formatter<ptree> : fmt::formatter<std::string>
{
template<typename Ctx>
auto format(ptree const& pt, Ctx& ctx) {
return format_to(ctx.out(), "'{}'", pt.get_value<std::string>());
}
};
int main() {
ptree pt;
pt.put("keyA", "valueA-1");
pt.put("keyB", "valueB");
pt.put("keyC", "valueC");
pt.add("keyA", "valueA-2"); // not replacing same key
std::map<std::string, ptree> m(pt.begin(), pt.end());
std::multimap<std::string, ptree> mm(pt.begin(), pt.end());
std::map<std::string, std::string> dict;
for (auto& [k,v]: pt) {
dict.emplace(k, v.get_value<std::string>());
}
fmt::print(
"map:\n\t{}\n"
"multimap:\n\t{}\n"
"dict:\n\t{}\n",
fmt::join(m, "\n\t"),
fmt::join(mm, "\n\t"),
fmt::join(dict, "\n\t")
);
}
版画
map:
("keyA", 'valueA-1')
("keyB", 'valueB')
("keyC", 'valueC')
multimap:
("keyA", 'valueA-1')
("keyA", 'valueA-2')
("keyB", 'valueB')
("keyC", 'valueC')
dict:
("keyA", "valueA-1")
("keyB", "valueB")
("keyC", "valueC")
奖励:来自字符串字典的 Ptree
template <typename MapLike>
ptree ptree_from_map(MapLike const& m) {
ptree pt;
for (auto const& [k,v]: m) {
pt.add(k, v);
}
return pt;
}