您可以专注于,以便属性树将为bool
值类型使用自定义翻译器。客户需要自定义行为时,该专业化必须可见(即#includ
)。这里有一个工作示例:
#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:
{
"number" : 42,
"enabled" : "Yes"
}
输出:
i=42 b=1
请注意,这个例子假定属性树是不区分大小写,并使用std::string
。如果你想BoolTranslator
更一般,你必须制作BoolTranslator
模板,并提供专业化的宽字符串和区分大小写的比较。
好了,哇。谢谢@Emile - 这有效。目前它与魔法无法区分。我还没有尝试输出,但它看起来像'假'输出只是偶然的工作;不应该有虚假的引号吗? – Arunas 2012-03-19 01:41:48
哈哈,当然,因为我正在为代码编写Boost测试用例,所以'str ==“0”'不属于'iequals(str,“yes”)' – Arunas 2012-03-19 02:03:04
@Arunas:是的,应该引用“false”的引号。我很惊讶,即使编译。如果你开始学习*部分模板专业化*,这个答案不会显得如此神奇。 :-) – 2012-03-19 02:52:07