简体   繁体   English

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

[英]Can I specialize std::begin and std::end for the return value of equal_range()?

The <algorithm> header provides std::equal_range() , as well as some containers having it as a member function. <algorithm>头提供了std::equal_range() ,以及一些将它作为成员函数的容器。 What bothers me with this function is that it returns a pair of iterators, making it tedious to iterate from the begin iterator to the end iterator. 让这个函数困扰我的是它返回一对迭代器,使得从开始迭代器迭代到结束迭代器变得繁琐。 I'd like to be able to use std::begin() and std::end() so that I can use the C++11 range-based for-loop. 我希望能够使用std::begin()std::end()这样我就可以使用C ++ 11基于范围的for循环。

Now, I've heard contradictory information in regards to specializing std::begin() and std::end() - I've been told that adding anything to the std namespace results in undefined behavior, whereas I have also been told that you can provide your own specializations of std::begin() and std::end() . 现在,我听说过关于专门化std::begin()std::end()矛盾信息 - 我被告知在std命名空间中添加任何内容都会导致未定义的行为,而我也被告知你可以提供自己的std::begin()std::end()

This is what I am doing right now: 这就是我现在正在做的事情:

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;
    }
}

And this does work: http://ideone.com/wHVfkh 这确实有效: http//ideone.com/wHVfkh

But I am wondering, what are the downsides to doing this? 但我想知道,这样做的缺点是什么? Is there a better way to do this? 有一个更好的方法吗?

17.6.4.2.1/1 The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. 17.6.4.2.1 / l的C ++程序的行为,如果其添加声明或定义到命名空间是未定义std命名空间内或一个命名空间std除非另有规定。 A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited. 只有当声明取决于用户定义的类型并且特化符合原始模板的标准库要求且未明确禁止时,程序才可以将任何标准库模板的模板特化添加到命名空间std

So yes, I believe that, technically, your code exhibits undefined behavior. 所以是的,我相信,从技术上讲,你的代码表现出不确定的行为。 Perhaps you can write a simple class that takes a pair of iterators in its constructor and implements begin() and end() methods. 也许你可以编写一个简单的类,它在构造函数中接受一对迭代器并实现begin()end()方法。 Then you can write something like 那你就可以写点东西了

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM