Reputation: 51
This is my first experience with boost::property_tree and I can't find a way to reproduce the way to get values from a tree following the documentation (How to Access Data in a Property Tree). This is the simple code that I wrote to experiment with a 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;
}
This is the output:
pi : 3.1415899999999999
name : John Doe
pi :
name :
pi optional : 3.14159
pi found : 3.1415899999999999
not found :
As can be seen tree.get_value("whatever")
returns no value, tree.get_value("null")
does not throw an exception and get_optional<whatever type>
does not compile. My experiment behaves way too different from the stated in the documentation. Excluding the line that causes the assertion error creates the output info file as expected.
My environment is:
MacOS 10.11.6
macbrew installed tools and libraries
boost 1.67
clang 7.0
meson build system
Upvotes: 1
Views: 4088
Reputation: 51
My bad, instead of using tree.get<float>("pi")
I copied and pasted tree.get_value<float>("pi")
that is meant for a different use. The question is answered with the help of @rafix07 comment. The get<type>("key path")
is the correct method to use.
Upvotes: 0
Reputation: 20938
You can draw your ptree as:
node1 is tree (has 2 children, data() of tree is "")
|
|- (node2) pi ----> data=3.14...
|
|- (node3) name --> data="Joe Doe"
[1]
As can be seen tree.get_value("whatever") returns no value
tree
is node and has 2 children (pi, name).
While calling
tree.get_value(defaultValue) // you are not passing PATH, but DEFAULT VALUE
above line is translated into
tree.get_child("").get_value(defaultValue)
so, ""
path exists because it is path to tree
node, and tree.data()
returns ""
- empty string for this path. So defaultValue
cannot be printed and you see empty string as output.
You should call get_value
only for children (use get_child
on tree
before calling this methid, it is described in boost reference), and parameter of get_value
is default value. So replace
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";
you will see 3.14
and Joe Doe
.
[2]
tree.get_value("null") does not throw an exception
is was described in [1] point. ""
path exists, and data()
for this path is empty string. So you cannot see null
string as default value.
[3]
// the commented line doesn't compile // std::cout << "not found : "
<< tree.get_value("null") << "\n";
This line cannot be compiled because ptree class doesn't have that method, I suppose you want to call this method:
template<typename Type>
unspecified get_value(const Type & default_value) const;
you defined Type
as int
, int
as function template parameter involves that default value can be only int
, not string.
Upvotes: 1