boost property_tree проблемы получения значений - PullRequest
0 голосов
/ 25 сентября 2018

Это мой первый опыт с boost :: property_tree, и я не могу найти способ воспроизвести способ получения значений из дерева, следуя документации ( Как получить доступ к данным в дереве свойств ),Это простой код, который я написал, чтобы экспериментировать с деревом свойств:

#include <iostream>
#include <string>

#include <boost/property_tree/info_parser.hpp>
#include <boost/property_tree/ptree.hpp>

namespace pt = boost::property_tree;

int main(int argc, char *argv[]) {
  pt::ptree tree;

  tree.put("pi", 3.14159);
  tree.put("name", "John Doe");

  for (auto &[key, value] : tree)
    std::cout << key << " : " << value.get_value<std::string>() << "\n";

  std::cout << "pi : " << tree.get_value("pi") << "\n";
  std::cout << "name : " << tree.get_value("name") << "\n";

  auto pi = tree.get_optional<float>("pi").get();
  std::cout << "pi optional : " << pi << "\n";

  auto pi_found = tree.find("pi");
  std::cout << "pi found : " << pi_found->second.data() << "\n";

  // the commented line doesn't compile
  // std::cout << "not found : " << tree.get_value<int>("null") << "\n";

  std::cout << "not found : " << tree.get_value("null") << "\n";

  // the line below causes an assertion error:
  // Assertion failed: (this->is_initialized()), function get, file /usr/local/include/boost/optional/optional.hpp, line 1191.
  // not found : Abort trap: 6
  std::cout << "not found : " << tree.get_optional<int>("null").get() << "\n";

  pt::write_info("ptree.info", tree);

  return 0;
}

Это вывод:

pi : 3.1415899999999999
name : John Doe
pi :
name :
pi optional : 3.14159
pi found : 3.1415899999999999
not found :

Как видно, tree.get_value("whatever") не возвращает значения, tree.get_value("null") не генерирует исключение и get_optional<whatever type> не компилируется.Мой эксперимент ведет себя слишком сильно отличается от заявленного в документации.Исключение строки, которая вызывает ошибку утверждения, создает ожидаемый выходной информационный файл.

Моя среда:

MacOS 10.11.6
macbrew installed tools and libraries
boost 1.67
clang 7.0
meson build system

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

Плохо, вместо использования tree.get<float>("pi") Я скопировал и вставил tree.get_value<float>("pi"), который предназначен для другого использования.Ответ на вопрос с помощью комментария @ rafix07.get<type>("key path") - правильный метод для использования.

0 голосов
/ 25 сентября 2018

Вы можете нарисовать свое дерево в виде:

node1 is tree (has 2 children, data() of tree is "")
 |
 |- (node2) pi ----> data=3.14...
 |
 |- (node3) name --> data="Joe Doe"

[1]

Как видно из дерева tree.get_value («что угодно») не возвращает значения

tree является узлом и имеет 2 дочерних элементов (pi, имя).При вызове

tree.get_value(defaultValue) // you are not passing PATH, but DEFAULT VALUE

указанная выше строка преобразуется в

tree.get_child("").get_value(defaultValue)

, поэтому путь "" существует, поскольку это путь к узлу tree, а tree.data() возвращает ""- пустая строка для этого пути.Так что defaultValue не может быть напечатано, и вы видите пустую строку в качестве вывода.Вы должны вызывать get_value только для детей (используйте get_child на tree перед вызовом этого метида, это описано в расширенном справочнике), а параметр get_value является значением по умолчанию.Поэтому заменить

  std::cout << "pi : " << tree.get_child("pi").get_value("PI is 4.0") << "\n";
  std::cout << "name : " << tree.get_child("name").get_value("noname") << "\n";

вы увидите, что 3.14 и Joe Doe.

[2]

tree.get_value ("null") небросить исключение

описано в пункте [1]."" путь существует, а data() для этого пути - пустая строка.Таким образом, вы не можете видеть null строку в качестве значения по умолчанию.

[3]

// закомментированная строка не компилируется // std :: cout << "не найдено: "</p>

<< tree.get_value (" null ") <<" \ n "; </p>

Эта строка не может быть скомпилирована, так как класс ptree не имеет этого метода, яПредположим, вы хотите вызвать этот метод:

  template<typename Type> 
  unspecified get_value(const Type & default_value) const;

вы определили Type как int, int, так как параметр шаблона функции предполагает, что значением по умолчанию может быть только int, а не строка.

...