简体   繁体   English

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

[英]Is this a bug in STL? Why do we need operator overloading in this Structure?

I came across this code for Equal_range, and being very new to C++, it is not clear to me why we need to overload the operator even though we have created a new compare function . 我碰到了Equal_range的这段代码,并且对C ++来说是个新手, 即使我创建了一个新的compare函数 ,也不清楚为什么我们需要重载运算符。

Moreover, could we have used: 此外,我们是否可以使用:

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

instead. 代替。

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

EDIT: The link to the code is http://en.cppreference.com/w/cpp/algorithm/equal_range 编辑:到代码的链接是http://en.cppreference.com/w/cpp/algorithm/equal_range

I think this is a bug in your STL implementation. 我认为这是您STL实现中的错误。 The C++ standard explicitly states it will not call operator< in this case: C ++标准明确声明在这种情况下不会调用operator <:

The elements are compared using operator< for the first version, and comp for the second . 对于第一个版本,使用operator <进行比较,而对于第二个版本,使用comp进行比较 Two elements, a and b are considered equivalent if (!(a<b) && !(b<a)) or if (!comp(a,b) && !comp(b,a)). 如果(!(a <b)&&!(b <a))或if(!comp(a,b)&&!comp(b,a)),则将两个元素a和b视为等效。

"First version" refers to the version where no comparison class is provided. “第一版本”是指未提供比较类的版本。 "second" refers to the version you used. “第二个”是指您使用的版本。

I tried this out on VS2013 but it doesn't even compile. 我在VS2013上进行了尝试,但它甚至没有编译。 The error is: 错误是:

error C2664: 'bool Comp::operator ()(const S &,int)' : cannot convert argument 1 from 'S' to 'int' 错误C2664:'bool Comp :: operator()(const S&,int)':无法将参数1从'S'转换为'int'

Unfortunately, the error is deep down inside Microsoft's obfuscated STL implementation. 不幸的是,该错误深入到Microsoft混淆的STL实现内部。 Why would it call operator()(const S&, int) instead of operator()(int, const S&) ? 为什么要调用operator()(const S&,int)而不是operator()(int,const S&)?

So I think Visual Studio's STL implementation is wrong. 因此,我认为Visual Studio的STL实现是错误的。 And if your compiler requires it, I think its STL is also wrong. 而且,如果您的编译器需要它,我认为它的STL也是错误的。 I wonder if they just never tested this where the third argument is not the same type as what is returned by the iterator. 我想知道他们是否从未测试过第三个参数与迭代器返回的类型不同的类型。

I would love to hear other people's thoughts on this. 我很想听听其他人对此的想法。

In your example code, your various methods of comparing all do different things; 在示例代码中,各种比较方法都有不同的作用。 the operator< overload allows you to compare an S with another S , where as the Comp struct allows you to compare an S with an int and vise-versa. operator<重载允许您将S与另一个S进行比较,而Comp结构允许您将Sint进行比较,反之亦然。

If you read the documentation for equal_range 如果您阅读了equal_range的文档

The elements are compared using operator< for the first version, and comp for the second 在第一个版本中使用operator <比较元素,在第二个版本中使用comp进行比较

You see that you need to be able to do both a[n] < a[i] and comp(a[n], val) , the first to compare items in the list to other items in the list, and the second to be able to compare items in the list to the val parameter of the equal_range call. 您将看到您既需要同时执行a[n] < a[i]comp(a[n], val) ,第一个将列表中的项目与列表中的其他项目进行比较,第二个将列表中的项目进行比较。能够将列表中的项目与equal_range调用的val参数进行比较。 Hence why you need both an operator overload and a comparison method. 因此,为什么同时需要运算符重载和比较方法。

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

相关问题 为什么需要运算符重载? - Why do I need operator overloading? C ++中的运算符重载 - 为什么我们需要将参数作为const&(...)传递? - Operator overloading in C++ - why do we need to pass parameter as const & (…)? 为什么在重载+ =运算符时我们必须通过引用返回 - Why do we have to return by reference when overloading += operator 为什么在后面的运算符重载中需要使用const? - Why do you need to use const in following operator overloading? 为什么我们甚至需要“delete[]”操作符? - Why do we even need the “delete[]” operator? stl容器的重载运算符&lt;&lt;() - Overloading operator<<() for stl containers 为什么重载“&gt;&gt;”和“&lt;&lt;”时需要通过引用传递? - Why do we need passing by reference when overloading “>>” and “<<”? 在cpp中的一元运算符重载中,如何决定我们需要在object的哪一侧放置运算符符号? - In unary operator overloading in cpp , how to decide on which side of an object do we need to put operator sign? 为什么对存储在STL容器中的类禁止重载operator&()? - Why is overloading operator&() prohibited for classes stored in STL containers? 为什么我的重载&lt;运算符不能用于STL排序 - Why isn't my overloading < operator not working for STL sort
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM