【问题标题】:How can i decide the datatype Boost Property Tree uses?我如何决定 Boost Property Tree 使用的数据类型?
【发布时间】:2020-09-24 10:08:08
【问题描述】:

我正在为一个项目使用 Boost 属性树,但遇到了一个问题。我是这样使用它的:

using Namespace boost::property_tree;
ptree proot;

int myInt = 5;

proot.put("Number", myInt);

write_json("myjson.json", proot);

如果我这样使用它,被保护的数据类型是字符串,而不是 int。我的意思的一个例子:

{ "Number": "5" } //what i get
{ "Number": 5 } //what i want

有办法改变吗?

【问题讨论】:

    标签: c++ json boost boost-propertytree


    【解决方案1】:

    我成功地尝试了类似的事情,并且它们运行良好,没有任何黑客,请在此处查看我的方法:

    Why does Boost property tree write_json save everything as string? Is it possible to change that?

    这需要一些努力(您必须提供自己的 JSON 编写器并专门化读取器的某些部分)但总的来说值得付出努力,因为您还将观察到许多场景的性能提升。

    【讨论】:

      【解决方案2】:

      不,您无法更改此行为,因为字符串值类型几乎已融入boost::property_tree。虽然从技术上讲,您可以使用与默认参数不同的模板类型参数,但您会丢失进入该库的大部分转换逻辑。

      作为一个有点古怪的替代方案,请考虑以下内容。

      #include <boost/property_tree/ptree.hpp>
      #include <boost/property_tree/json_parser.hpp>
      
      using namespace boost::property_tree;
      using boost::property_tree::json_parser::create_escapes;
      
      void writeJsonValue(std::ostream& stream, const ptree& pt)
      {
          const auto raw = pt.get_value<std::string>();
      
          if (raw == "true" || raw == "false") {
              stream << raw;
              return;
          }
      
          if (const auto integral = pt.get_value_optional<int>())
              stream << *integral;
          else
              stream << '"' << create_escapes(raw) << '"';
      }
      

      这从本质上恢复了一些预定义的类型信息丢失。您可以在 Boost 的 json 输出函数的修改版本中使用它:

      void writeJson(std::ostream& stream, const ptree& pt, int indent = 0)
      {
          static const auto indentStr = [](int level) { return std::string(4 * level, ' '); };
      
          if (indent > 0 && pt.empty())
              writeJsonValue(stream, pt);
          else if (indent > 0 && pt.count(std::string()) == pt.size()) {
              stream << "[\n";
      
              for (auto it = pt.begin(); it != pt.end(); ++it) {
                  stream << indentStr(indent + 1);
                  writeJson(stream, it->second, indent + 1);
                  if (boost::next(it) != pt.end())
                      stream << ',';
                  stream << '\n';
              }
      
              stream << indentStr(indent) << ']';
          } else {
              stream << "{\n";
      
              for (auto it = pt.begin(); it != pt.end(); ++it) {
                  stream << indentStr(indent + 1);
                  stream << '"' << create_escapes(it->first) << "\": ";
                  writeJson(stream, it->second, indent + 1);
                  if (boost::next(it) != pt.end())
                      stream << ',';
                  stream << '\n';
              }
      
              stream << indentStr(indent) << '}';
          }
      }
      

      为您的数据调用它,例如作为

       writeJson(std::cout, proot);
      

      输出应该是

      {
          "Number": 5
      }
      

      【讨论】:

      • 感谢您的回答。当我回到我的电脑时,我将对此进行测试。 @lubgr
      • 终于有时间测试了。它工作得很好。非常感谢你! @lubgr
      猜你喜欢
      • 2016-07-16
      • 1970-01-01
      • 2017-10-28
      • 2020-03-31
      • 2013-01-24
      • 2015-05-28
      • 1970-01-01
      • 2015-01-18
      相关资源
      最近更新 更多