Boost.PropertyTree 遍历一些空树时崩溃
Boost.PropertyTree crash when iterating over some empty trees
循环空 Boost.PropertyTree 的 children 通常是 no-op:
ptree empty;
for (auto const& elements : empty)
{
std::cout << "child\n"; // Executed 0 times, as expected
}
但有时它会因访问冲突而崩溃:
ptree empty;
for (auto const& elements : empty.get_child("non-existent", ptree{})))
{
std::cout << "child\n";
}
Access violation reading location 0xFFFFFFFFFFFFFFFF.
(Inside basic_ptree<K, D, C>::begin() const
)
现在显然 empty
没有 child "non-existent",但是提供了默认值 (ptree{}
)。我们从第一个示例中知道可以循环遍历一个空集合。
usual way to detect a read failure 不起作用,因为这是 Boost.PropertyTree 中的访问冲突/未定义行为。
如何区分第一类和第二类空 属性 树,从而避免迭代爆炸的类型?
问题是 Boost.PropertyTree 通过 const 引用采用默认值(临时)。而临时 ,甚至在 begin
被调用之前。
您无法在运行时检测到此问题。解决方法是使用非临时空 ptree
作为默认值。这可以是 const ptree
,因此您可以在不同的通话之间共享它。另一种解决方案是使用 this trick.
循环空 Boost.PropertyTree 的 children 通常是 no-op:
ptree empty;
for (auto const& elements : empty)
{
std::cout << "child\n"; // Executed 0 times, as expected
}
但有时它会因访问冲突而崩溃:
ptree empty;
for (auto const& elements : empty.get_child("non-existent", ptree{})))
{
std::cout << "child\n";
}
Access violation reading location 0xFFFFFFFFFFFFFFFF.
(Inside
basic_ptree<K, D, C>::begin() const
)
现在显然 empty
没有 child "non-existent",但是提供了默认值 (ptree{}
)。我们从第一个示例中知道可以循环遍历一个空集合。
usual way to detect a read failure 不起作用,因为这是 Boost.PropertyTree 中的访问冲突/未定义行为。
如何区分第一类和第二类空 属性 树,从而避免迭代爆炸的类型?
问题是 Boost.PropertyTree 通过 const 引用采用默认值(临时)。而临时 begin
被调用之前。
您无法在运行时检测到此问题。解决方法是使用非临时空 ptree
作为默认值。这可以是 const ptree
,因此您可以在不同的通话之间共享它。另一种解决方案是使用 this trick.