C++ 属性树:无法设置默认属性值?

C++ 属性树:无法设置默认属性值?,c++,boost,boost-propertytree,C++,Boost,Boost Propertytree,下面的代码从ini文件中读取属性。但是,我希望属性具有默认值。在读取ini文件之前,我使用put,然后使用get检索属性 如果不需要默认值,并且程序输出的testval为2,则该选项可以正常工作。但是,如果我注释掉ini文件中的条目(如图所示),程序将输出没有这样的节点(foo.bar)。换句话说,pt.put没有设置默认值。你知道为什么吗?我的电话号码是105300 #include <iostream> #include <boost/property_tree/ptree

下面的代码从ini文件中读取属性。但是,我希望属性具有默认值。在读取ini文件之前,我使用
put
,然后使用
get
检索属性

如果不需要默认值,并且程序输出的
testval为2
,则该选项可以正常工作。但是,如果我注释掉ini文件中的条目(如图所示),程序将输出
没有这样的节点(foo.bar)
。换句话说,
pt.put
没有设置默认值。你知道为什么吗?我的电话号码是105300

#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>

int main() {
   boost::property_tree::ptree pt;
   int testval = 0;

   try {
      pt.put("foo.bar", 1);               // set a default value
      boost::property_tree::ini_parser::read_ini("test.ini", pt);

      testval = pt.get<int>("foo.bar");

   } catch(boost::property_tree::ptree_error const& e) {
      std::cout << e.what() << '\n';
      return 1;
   }

   std::cout << "testval is " << testval << '\n';
   return 0;
}

根据
的文档,请阅读ini()

清除属性树的现有内容。如果出现错误,则未修改属性树


因此,您事先所做的一切都无关紧要。

根据
read_ini()
的文档:

清除属性树的现有内容。如果出现错误,则未修改属性树


因此,无论您事先做什么都无关紧要。

我认为您对默认值的使用感到困惑

现在的情况是: 如果在读取文件之前将
foo.bar
的值更改为1,则读取文件将覆盖从文件读取的内容
foo.bar
。如果在ini文件中注释掉
bar=2
foo.bar
没有值

如果在读取_ini后将put的值更改为1,则从该点开始的值为1是正常的
put()
foo.bar
的值设置为1

如果要在未定义
foo.bar
时为
get()
设置返回的默认值,请在调用
get()
时指定默认值,如下所示:

testval = pt.get<int>("foo.bar", 1);  // gets foo.bar from pt, or 1 if not found.

我认为您对默认值的使用感到困惑

现在的情况是: 如果在读取文件之前将
foo.bar
的值更改为1,则读取文件将覆盖从文件读取的内容
foo.bar
。如果在ini文件中注释掉
bar=2
foo.bar
没有值

如果在读取_ini后将put的值更改为1,则从该点开始的值为1是正常的
put()
foo.bar
的值设置为1

如果要在未定义
foo.bar
时为
get()
设置返回的默认值,请在调用
get()
时指定默认值,如下所示:

testval = pt.get<int>("foo.bar", 1);  // gets foo.bar from pt, or 1 if not found.

但是如果我把
pt.put
放在
read_ini
之后,ini文件中的值总是被忽略,并且我总是得到
testval是1
?但是如果我把
pt.put
放在
read_ini
之后,ini文件中的值总是被忽略,而且我总是得到
testval为1
…?默认版本的
get
的问题是,您无法知道(a)
foo.bar
是否不在ini文件中,这是一个有效的允许条件,或者(b)
foo.bar
是否存在,但其值不能解析为int,必须将其标记为错误。因此,除非我误解了,否则这个版本的
get
是无用的。默认值的概念是在文件中没有定义的情况下获取一个值。如果您对默认值有不同的定义,您将很难找到问题的答案。这个版本的get很有用,因为我们希望get(“foo.bar”,1)总是返回一个int。如果您想知道它是否不是int,请使用get(“foo.bar”),但是,为什么要覆盖文件中的内容?请同意您对默认值的定义。问题在于
property_tree
必须负责(1)从ini文件读取密钥/val,(2)如果密钥不在文件中,则提供默认值,以及(3)如果密钥在文件中,则确认值格式正确。使用
get
的默认值只能得到1和2。如果用户错误地在ini文件中输入了
a
而不是
1
,并且您使用了默认的
get
,那么您最终会默默地忽略用户的错误并使用默认值,因此我不相信默认的
get
是有用的。属性树不是作为文件验证程序构建的。它被设计成程序设置的值树。这就是文件加载和保存与类分开的原因。如果要对ini文件的内容进行类型验证,必须编写代码,将所有值读取为字符串并从中进行分析/验证。不,但它是作为数据验证器构建的,因此如果文件中的坏数据不能正确分析,它会抛出
ptree\u bad\u data
。问题在于糟糕的设计:除非您准备捕捉
ptree\u bad\u路径
并自己处理缺失键的默认值,并且还捕捉
ptree\u bad\u数据
,然后通知用户其ini文件不正确,否则似乎无法处理实际的ini文件使用。除非你走到树上,自己检查所有的东西,这比一开始就编写解析器要困难得多。尽管如此,+1,感谢您不厌其烦地回复。默认版本的
get
的问题在于,您无法知道(a)
foo.bar
是否不在ini文件中,这是一个有效的允许条件,或者(b)
foo.bar
是否存在,但其值无法解析为int,必须将其标记为错误。因此,除非我误解了,否则这个版本的
get
是无用的。默认值的概念是在文件中没有定义的情况下获取一个值。如果您对默认值有不同的定义,您将很难找到问题的答案。这个版本的get很有用,因为我们希望get(“foo.bar”,1)总是返回一个int。如果您想知道它是否不是int,请使用get(“foo.bar”),但是,为什么要覆盖文件中的内容?请同意您的de
testval = pt.get("foo.bar", 1);