为什么std :: list的相等比较不能通过编译,而T是EqualityComparable

时间:2016-05-09 13:20:26

标签: c++ list stl equality

我需要比较两个列表是否相等,所以我在VS2005项目中写下以下代码

#include <list>

class sitesInfo
{
public:
    bool operator==(const sitesInfo &rh)
    {
        return this->a == rh.a;
    }
private:
    int a;
};

int _tmain(int argc, _TCHAR* argv[])
{
    std::list<sitesInfo> list1;
    std::list<sitesInfo> list2;

    bool ret = (list1 == list2);

    return 0;
}

这里sitesInfo是EqualityComparable,这是c ++标准所要求的:

表96 - 容器要求

enter image description here

为什么我会遇到以下编译错误,导致我无法比较两个列表?

vs2005\vc\include\xutility(2476) : error C2678: binary '==' : no operator found which takes a left-hand operand of type 'const sitesInfo' (or there is no acceptable conversion)
d:\my documents\visual studio 2005\projects\test\test\test.cpp(10): could be 'bool sitesInfo::operator ==(const sitesInfo &)'
        while trying to match the argument list '(const sitesInfo, const sitesInfo)'
1>        e:\program files\vs2005\vc\include\xutility(2602) : see reference to function template instantiation 'std::pair<_Ty1,_Ty2> std::_Mismatch<_InIt1,_InIt2,std::forward_iterator_tag>(_InIt1,_InIt1,_InIt2,_InItCats,std::_Range_checked_iterator_tag)' being compiled
        with
        [
            _Ty1=std::list<sitesInfo>::_Const_iterator<false>,
            _Ty2=std::list<sitesInfo>::_Const_iterator<true>,
            _InIt1=std::list<sitesInfo>::_Const_iterator<false>,
            _InIt2=std::list<sitesInfo>::_Const_iterator<true>,
            _InItCats=std::forward_iterator_tag
        ]
        e:\program files\vs2005\vc\include\xutility(2674) : see reference to function template instantiation 'bool std::_Equal<std::list<_Ty>::_Const_iterator<_Secure_validation>,_InIt2,std::_Iter_random_helper<_Cat1,_Cat2>::_Iter_random_cat>(_InIt1,_InIt1,_InIt2,_InItCats,std::_Range_checked_iterator_tag)' being compiled
       with
                _Ty=sitesInfo,
            _Secure_validation=false,
            _InIt2=std::list<sitesInfo>::_Const_iterator<true>,
            _Cat1=std::list<sitesInfo>::_Const_iterator<true>::iterator_category,
            _Cat2=std::list<sitesInfo>::_Const_iterator<true>::iterator_category,
            _InIt1=std::list<sitesInfo>::_Const_iterator<false>,
            _InItCats=std::_Iter_random_helper<std::list<sitesInfo>::_Const_iterator<true>::iterator_category,std::list<sitesInfo>::_Const_iterator<true>::iterator_category>::_Iter_random_cat
        ]
        e:\program files\vs2005\vc\include\list(1261) : see reference to function template instantiation 'bool std::equal<std::list<_Ty>::_Const_iterator<_Secure_validation>,std::list<_Ty>::_Const_iterator<_Secure_validation>>(_InIt1,_InIt1,_InIt2)' being compiled
        with
        [
            _Ty=sitesInfo,
            _Secure_validation=true,
            _InIt1=std::list<sitesInfo>::_Const_iterator<true>,
            _InIt2=std::list<sitesInfo>::_Const_iterator<true>
        ]
        d:\my documents\visual studio 2005\projects\test\test\test.cpp(23) : see reference to function template instantiation 'bool std::operator ==<sitesInfo,std::allocator<_Ty>>(const std::list<_Ty> &,const std::list<_Ty> &)' being compiled
        with
        [
            _Ty=sitesInfo
        ]

我只能通过定义参数类型为operator==

的全局const sitesInfo&来编译它
bool operator==(const sitesInfo &rh, const sitesInfo &rs)

2 个答案:

答案 0 :(得分:3)

您的会员operator==的问题是它未标记为const。当std::list检查相等性时,它会对两个const元素进行检查。这意味着您的operator==会被忽略,因为它未标记为const,因此无法在const对象上调用它。

要解决此问题,我们只需将该功能标记为const,如

bool operator==(const sitesInfo &rh) const
{
    return this->a == rh.a;
}

现在它将compile and run

自由函数作为自由函数没有const限定条件,它需要两个const个对象。如果你有

bool operator==(sitesInfo &rh, sitesInfo &rs)

然后,当您尝试删除对象的常量时,将无法编译。

答案 1 :(得分:1)

仔细阅读错误。您的运营商:

 bool operator==(const sitesInfo &rh)
{
    return this->a == rh.a;
}

适用于非const对象和任何右侧,但对于const对象,您必须提供如下运算符:

 bool operator==(const sitesInfo &rh) const
{
    return this->a == rh.a;
}

运算符必须是const的原因是列表运算符==可以在const list s上运行:

bool operator==( const list& lhs, const list& rhs ); // template parameters 
                                                     // omitted for the sake of clarity

因此它只能调用其元素比较运算符的const版本。