我可以将std :: begin和std :: end专门用于equal_range()的返回值吗?

时间:2013-10-11 19:41:30

标签: c++ c++11 stl iterator template-specialization

<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

但我想知道,这样做的缺点是什么?有更好的方法吗?

1 个答案:

答案 0 :(得分:7)

  

17.6.4.2.1 / 1 如果C ++程序向名称空间std或名称空间添加声明或定义,则其行为是未定义的   除非另有说明,否则在std命名空间内。程序可以添加一个   任何标准库模板到命名空间的模板专门化   std仅当声明取决于用户定义的类型和   专业化符合标准库的要求   原始模板并未明确禁止。

所以是的,我相信,从技术上讲,您的代码表现出未定义的行为。也许你可以编写一个简单的类,它在构造函数中使用一对迭代器并实现begin()end()方法。然后你可以写点像

for (const auto& elem: as_range(equal_range(...))) {}