<algorithm>
标题提供std::equal_range()
,以及将其作为成员函数的一些容器。让这个函数困扰我的是它返回一对迭代器,使得从开始迭代器迭代到结束迭代器变得繁琐。我希望能够使用std::begin()
和std::end()
,以便我可以使用基于C ++ 11范围的for循环。
现在,我听说过关于专门化std::begin()
和std::end()
的矛盾信息 - 我被告知在std命名空间中添加任何内容会导致未定义的行为,而我也被告知您可以提供自己的std::begin()
和std::end()
专精。
这就是我现在正在做的事情:
namespace std
{
template<typename Iter, typename = typename iterator_traits<Iter>::iterator_category>
Iter begin(pair<Iter, Iter> const &p)
{
return p.first;
}
template<typename Iter, typename = typename iterator_traits<Iter>::iterator_category>
Iter end(pair<Iter, Iter> const &p)
{
return p.second;
}
}
这确实有效:http://ideone.com/wHVfkh
但我想知道,这样做的缺点是什么?有更好的方法吗?
答案 0 :(得分:7)
17.6.4.2.1 / 1 如果C ++程序向名称空间
std
或名称空间添加声明或定义,则其行为是未定义的 除非另有说明,否则在std
命名空间内。程序可以添加一个 任何标准库模板到命名空间的模板专门化std
仅当声明取决于用户定义的类型和 专业化符合标准库的要求 原始模板并未明确禁止。
所以是的,我相信,从技术上讲,您的代码表现出未定义的行为。也许你可以编写一个简单的类,它在构造函数中使用一对迭代器并实现begin()
和end()
方法。然后你可以写点像
for (const auto& elem: as_range(equal_range(...))) {}