这个C++示例是可移植的吗?

lez*_*lon 8 c++ stl visual-studio-2010

下面的这个问题,我试图复制粘贴发现的例子在这里在VS2010:

#include <algorithm>
#include <vector>
#include <iostream>

struct S
{
    int number;
    char name;

    S ( int number, char name  )
        : number ( number ), name ( name )
    {}

    // only the number is relevant with this comparison
    bool operator< ( const S& s ) const
    {
        return number < s.number;
    }
};

struct Comp
{
    bool operator() ( const S& s, int i )
    {
        return s.number < i;
    }

    bool operator() ( int i, const S& s )
    {
        return i < s.number;
    }
};

int main()
{
    std::vector<S> vec = { {1,'A'}, {2,'B'}, {2,'C'}, {2,'D'}, {3,'F'}, {4,'G'} }; //this syntax won't compile in VS2010, so you can leave an empty vector here

    auto p = std::equal_range(vec.begin(),vec.end(),2,Comp());

    for ( auto i = p.first; i != p.second; ++i )
        std::cout << i->name << ' ';
}
Run Code Online (Sandbox Code Playgroud)

这将在发布模式下正常编译,但在调试模式下,它将无法编译.原因是在调试模式下,实现将使用给定的谓词检查迭代器范围是否已经排序:

template<class _FwdIt,
    class _Pr> inline
    void _Debug_order2(_FwdIt _First, _FwdIt _Last, _Pr _Pred,
        _Dbfile_t _File, _Dbline_t _Line, forward_iterator_tag)
    {   // test if range is ordered by predicate, forward iterators
    for (_FwdIt _Next = _First; _First != _Last && ++_Next != _Last; ++_First)
        if (_DEBUG_LT_PRED(_Pred, *_Next, *_First))
            _DEBUG_ERROR2("sequence not ordered", _File, _Line);
    }
Run Code Online (Sandbox Code Playgroud)

这最终要求:

template<class _Pr, class _Ty1, class _Ty2> inline
    bool _Debug_lt_pred(_Pr _Pred,
        const _Ty1& _Left, const _Ty2& _Right,
        _Dbfile_t _File, _Dbline_t _Line)
    {   // test if _Pred(_Left, _Right) and _Pred is strict weak ordering
    if (!_Pred(_Left, _Right))
        return (false);
    else if (_Pred(_Right, _Left))
        _DEBUG_ERROR2("invalid operator<", _File, _Line);
    return (true);
    }
Run Code Online (Sandbox Code Playgroud)

除了在我的情况下,没有operator()可以采取左右"S"的论点.那么,Visual实现中是否存在错误?或者原始的例子不应该是便携式的?我想我可以通过提供第三个operator()重载来使它工作,但它似乎应该没有

谢谢

Rei*_*ica 12

标准中没有任何内容要求比较器可以使用范围内的两个对象进行调用.这是VS 2010使用的标准库中的一个错误.

以下是所有相关要求(引用C++ 11):

[lower.bound]§1+ 2:

1 要求:该元件e[first,last)应相对于所述表达被划分... comp(e, value).

2 返回:最远的迭代器i的范围内[first,last],使得对于任何迭代j范围[first,i)以下相应条件成立:... comp(*j, value) != false.

[upper.bound]§1+ 2:

1 要求:该元件e[first,last)应相对于所述表达被划分... !comp(value, e).

2 返回:最远的迭代器i的范围内[first,last],使得对于任何迭代j范围[first,i)以下相应条件成立:... comp(value, *j) == false.

[equal.range]§1+ 2:

1 要求:该元件e[first,last)应相对于所述表达式...被分割comp(e, value)!comp(value, e).此外,所有元素e[first, last),...... comp(e, value)应暗示!comp(value, e).

2 返回:

...

make_pair(lower_bound(first, last, value, comp),
          upper_bound(first, last, value, comp))
Run Code Online (Sandbox Code Playgroud)

(省略号用于非比较器版本).