这是STL中的错误吗?为什么我们在这个结构中需要运算符重载?

时间:2014-10-13 19:57:11

标签: c++ stl operator-overloading

我遇到了Equal_range的这段代码,并且对C ++来说还是一个新手,我不清楚为什么我们需要重载运算符,即使我们已经创建了一个新的比较函数

此外,我们可以使用:

bool compare( const S& s, const S& s2 )
{
    return s.number < s2.number;
}

代替。

#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()
{
    // note: not ordered, only partitioned w.r.t. S defined below
    std::vector<S> vec = { {1,'A'}, {2,'B'}, {2,'C'}, {2,'D'}, {4,'G'}, {3,'F'} };

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

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

编辑:代码的链接是http://en.cppreference.com/w/cpp/algorithm/equal_range

2 个答案:

答案 0 :(得分:4)

我认为这是您的STL实施中的一个错误。 C++ standard明确声明它不会调用operator&lt;在这种情况下:

  

使用运算符&lt;来比较元素。对于第一个版本,和    comp for second 。两个元素a和b被认为是等价的   if(!(a&lt; b)&amp;&amp;!(b&lt; a))或if(!comp(a,b)&amp;&amp;!comp(b,a))。

&#34;第一版&#34;指的是没有提供比较类的版本。 &#34;第二&#34;是指您使用的版本。

我在VS2013上尝试了这个,但它甚至没有编译。错误是:

  

错误C2664:&#39; bool Comp :: operator()(const S&amp;,int)&#39; :无法转换   来自&#39; S&#39;到&#39; int&#39;

不幸的是,这个错误在微软的混乱STL实现中很深。为什么它会调用operator()(const S&amp;,int)而不是operator()(int,const S&amp;)?

所以我认为Visual Studio的STL实现是错误的。如果您的编译器需要它,我认为它的STL也是错误的。我想知道他们是否从未测试过第三个参数与迭代器返回的类型不同的类型。

我很想听听别人对此的看法。

答案 1 :(得分:2)

在您的示例代码中,您的各种比较方法都做不同的事情; operator<重载允许您将S与另一个S进行比较,其中Comp结构允许您将Sint进行比较而反之亦然。

如果您阅读了equal_range

的文档
  

使用运算符&lt;来比较元素。对于第一个版本,和   comp为第二个

您看到您需要同时执行a[n] < a[i]comp(a[n], val),第一个将列表中的项目与列表中的其他项目进行比较,第二个能够比较项目在列表中val调用的equal_range参数。因此,为什么需要运算符重载和比较方法。