我最近开始更喜欢自由函数std::next
以及std::prev
显式复制和递增/递减迭代器。现在,我在一个非常具体的案例中看到了奇怪的行为,如果能帮助我揭开它的神秘面纱,我将不胜感激。
我有一个插值/外插函数在boost::any_range
一些X_type
. 范围类型的完整定义是:
boost::any_range <
const X_type,
boost::random_access_traversal_tag,
const X_type,
std::ptrdiff_t
>
在any_range
这种特殊情况下,从 a 中分配了iterator_range
两个指向 的指针const X_type
,这用作 aX_type
的大约一半data()
区域的视图vector<char>
。
在 MSVC 2010 中编译我的应用程序,一切正常。在 MinGW g++ 4.7.0 中编译相同的代码,它似乎挂在一个特定的位置,然后我将其缩小到这个(稍微缩写):
// Previously ensured conditions:
// 1) xrange is nonempty;
// 2) yrange is the same size as xrange.
auto x_equal_or_greater =
std::lower_bound(std::begin(xrange),std::end(xrange),xval);
if (x_equal_or_greater == std::end(xrange))
{
return *yit_from_xit(std::prev(x_equal_or_greater),xrange,yrange);
}
单步执行 gdb 中的代码,我发现它并没有卡住,只是需要很长时间才能从单个std::prev
调用中返回——在 libstdc++ 中,它是根据操作符std::advance
并最终实现的+=
。
只需将return
行替换为:
auto xprev=x_equal_or_greater;
--xprev;
return *yit_from_xit(xprev,xrange,yrange);
性能再次很棒,几乎没有延迟。
我知道使用类型擦除迭代器(那些any_range
)的开销,但即便如此,上述两种情况真的应该承担如此不同的成本吗?还是我做错了什么?