【发布时间】:2015-11-01 15:51:06
【问题描述】:
我最近回顾了不久前实现的 algorithm 并发现 it can be improved 不仅可以在 RandomAccessIterator 输入范围上进行操作,而且甚至可以在 ForwardIterator 1 上进行操作(多通道保证仍然是要求)。
我决定通过修改代码中的所有位置来简单地降级需求,目前使用迭代器之间的简单差异,以使用std::distance 代替。 std::distancealgorithm described here。由于std::distance 算法的本质,修改不仅仅是搜索和替换,即:
- 对于算法内部使用的有序容器,我将所有出现的
operator <或std::less< iterator >/std::less<>替换为:
auto const less = [ibeg = std::cbegin(input)] (iterator const & l, iterator const & r)
{
return std::distance(ibeg, l) < std::distance(ibeg, r);
};
说,std::set< iterator > x; 修改为 std::set< iterator, decltype(less) > x{less};。
- 对于算法内部使用的无序容器(
value_type是iterator)我使用std::hash< std::intptr_t > h;哈希函数进行简单的差异h(lhs - rhs)(实际上是哈希值的 xor 组合,但它在这里无关紧要)对于一些固定的iterator lhs和一些变化的iterator rhs。修改为h(std::distance(lhs, rhs))。
前一点是正确的,但后一点显然不是。由于rhs 无法从lhs 中恢复,只能通过简单的递增,并且无法先验地知道要做什么:递增lhs 以达到rhs 或递增rhs 以达到lhs.
但上面的哈希仍然有效。这很奇怪......因为有时,当lhs > rhs(在某种意义上),应该有访问冲突(有时)。说,如果:
std::list< int > input{1, 2, 3, 4};
auto a = std::begin(input), b = std::next(lhs, 2);
然后增量,包含在std::distance(b, a) 中,不应停止并最终到达尚未分配的内存页面的边界。但是 AV 从来没有出现在我的程序中。 std::distance 总是返回非负数。
是未定义的行为还是允许为任何一对 ForwardIterator-s 应用 std::distance? -stdlib= 是 libc++。
【问题讨论】:
标签: c++ algorithm c++11 stl c++14