如何更改的boost :: property_tree读取字符串转换为bool [英] Change how boost::property_tree reads translates strings to bool
问题描述
我已经得到了失去在升压property_tree的头文件,并鉴于缺乏低层周围的文档,我已经决定要问最简单的方式就是用于超越流译者改怎么布尔值被解析。
I've gotten lost in the header files for the boost property_tree and given the lack of documentation around the lower layers, I've decided to ask what the easy way is to over-ride the stream translator to change how Boolean values are parsed.
的问题是,对一个属性树的输入侧,也有用户,他们可以修改配置文件。布尔值可能在许多方面被指定,例如:
The problem is that on the input side of a property tree, there are users, and they can modify the configuration files. A Boolean value might be specified in a number of ways, like:
dosomething.enabled=true
dosomething.enabled=trUE
dosomething.enabled=yes
dosomething.enabled=ON
dosomething.enabled=1
默认行为是检查0或1,然后用
The default behaviour is to check for 0 or 1 and then use
std::ios_base::boolalpha
获得流尝试以适当的方式来解析该值当前语言环境......如果我们尝试将配置文件发送到国际客户可能是疯了。
to get the stream to try to parse the value in the appropriate manner for the current locale...which could be insane if we try to send a configuration file to international customers.
那么,有什么改变这种行为,或仅bool的最简单的方法?不仅是最容易实现的,但最容易使用的 - 所以,我的班从iptree导出用户并不需要做一些特殊的布尔值
So what's the easiest way to override this behaviour or bool only? Not only easiest to implement, but easiest to use - so that the users of my class which derives from iptree don't need to do something special for Boolean values.
谢谢!
推荐答案
您可以专门的boost :: property_tree :: translator_between
这样一个属性树将使用自定义翻译为布尔
值类型。这种专业化必须是可见的(即 #includ
编辑)希望通过定制行为的客户。这里有一个工作的例子:
You can specialize boost::property_tree::translator_between
so that a property tree will use a custom translator for a bool
value type. This specialization must be visible (i.e. #includ
ed) by clients wanting the customized behavior. Here's a working example:
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/algorithm/string/predicate.hpp>
// Custom translator for bool (only supports std::string)
struct BoolTranslator
{
typedef std::string internal_type;
typedef bool external_type;
// Converts a string to bool
boost::optional<external_type> get_value(const internal_type& str)
{
if (!str.empty())
{
using boost::algorithm::iequals;
if (iequals(str, "true") || iequals(str, "yes") || str == "1")
return boost::optional<external_type>(true);
else
return boost::optional<external_type>(false);
}
else
return boost::optional<external_type>(boost::none);
}
// Converts a bool to string
boost::optional<internal_type> put_value(const external_type& b)
{
return boost::optional<internal_type>(b ? "true" : "false");
}
};
/* Specialize translator_between so that it uses our custom translator for
bool value types. Specialization must be in boost::property_tree
namespace. */
namespace boost {
namespace property_tree {
template<typename Ch, typename Traits, typename Alloc>
struct translator_between<std::basic_string< Ch, Traits, Alloc >, bool>
{
typedef BoolTranslator type;
};
} // namespace property_tree
} // namespace boost
int main()
{
boost::property_tree::iptree pt;
read_json("test.json", pt);
int i = pt.get<int>("number");
int b = pt.get<bool>("enabled");
std::cout << "i=" << i << " b=" << b << "\n";
}
test.json:
test.json:
{
"number" : 42,
"enabled" : "Yes"
}
输出:
i=42 b=1
请注意,这个例子假定属性树不区分大小写,使用的std ::字符串
。如果你想 BoolTranslator
更一般情况下,你必须让 BoolTranslator
的模板,并提供广泛的专业字符串和区分大小写的比较。
Please note that this example assumes that the property tree is case insensitive and uses std::string
. If you want BoolTranslator
to be more general, you'll have to make BoolTranslator
a template and provide specializations for wide strings and case sensitive comparisons.
这篇关于如何更改的boost :: property_tree读取字符串转换为bool的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!