std :: map和std :: pair的问题

时间:2010-04-15 05:46:17

标签: c++ stl operator-overloading stdmap std-pair

我想要执行一个小程序来测试一些东西

#include <map>
#include <iostream>
using namespace std;

struct _pos{
        float xi;
        float xf;

        bool operator<(_pos& other){

                return this->xi < other.xi;
        }
};

struct _val{

        float f;
};

int main()
{
        map<_pos,_val> m;

        struct  _pos k1 = {0,10};
        struct  _pos k2 = {10,15};

        struct  _val v1 = {5.5};
        struct  _val v2 = {12.3};                                                                   

        m.insert(std::pair<_pos,_val>(k1,v1));
        m.insert(std::pair<_pos,_val>(k2,v2));

        return 0;
}

问题是,当我尝试编译它时,我收到以下错误

$ g++ m2.cpp -o mtest
In file included from /usr/include/c++/4.4/bits/stl_tree.h:64,
                 from /usr/include/c++/4.4/map:60,
                 from m2.cpp:1:
/usr/include/c++/4.4/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = _pos]’:
/usr/include/c++/4.4/bits/stl_tree.h:1170:   instantiated from ‘std::pair<typename std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(const _Val&) [with _Key = _pos, _Val = std::pair<const _pos, _val>, _KeyOfValue = std::_Select1st<std::pair<const _pos, _val> >, _Compare = std::less<_pos>, _Alloc = std::allocator<std::pair<const _pos, _val> >]’
/usr/include/c++/4.4/bits/stl_map.h:500:   instantiated from ‘std::pair<typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator, bool> std::map<_Key, _Tp, _Compare, _Alloc>::insert(const std::pair<const _Key, _Tp>&) [with _Key = _pos, _Tp = _val, _Compare = std::less<_pos>, _Alloc = std::allocator<std::pair<const _pos, _val> >]’
m2.cpp:30:   instantiated from here
/usr/include/c++/4.4/bits/stl_function.h:230: error: no match for ‘operator<’ in ‘__x < __y’
m2.cpp:9: note: candidates are: bool _pos::operator<(_pos&)
$ 

我认为宣布运营商&lt;关键是解决问题,但它仍然存在。

可能出现什么问题?

提前致谢。

3 个答案:

答案 0 :(得分:25)

问题在于:

bool operator<(_pos& other)

应该是这样的:

bool operator<(const _pos& other) const {
//             ^^^^               ^^^^^

如果没有第一个const,则比较的右侧(b中的a < b)不能为const,因为没有const函数可以修改其论点。

如果没有第二个const,则比较的左侧(a中的a < b)不能为const,因为没有const功能可以修改this

在内部,地图的关键字始终为const


应该注意,您应该更喜欢使用非成员函数。也就是说,更好的是自由功能:

bool operator<(const _pos& lhs, const _pos& rhs)
{
    return lhs.xi < rhs.xi;
}

与您的类在同一名称空间中。 (对于我们的例子,就在它下面。)


顺便说一句,在C ++中,不需要为struct添加结构类型变量的声明前缀。这是完美的,也是首选:

    _pos k1 = {0,10};
    _pos k2 = {10,15};

    _val v1 = {5.5};
    _val v2 = {12.3};

(虽然你的类型名称是以非正统方式命名的。:P)


最后,您应该更喜欢make_pair实用程序函数来进行配对:

    m.insert(std::make_pair(k1,v1));
    m.insert(std::make_pair(k2,v2));

它使您免于必须写出对的类型,并且通常更容易阅读。 (特别是当更长的类型名称出现时。)

答案 1 :(得分:4)

小于运算符的签名需要为bool operator<(const _pos& other) const,否则map不能在const函数中使用此运算符,因为此成员函数声明为非const。

答案 2 :(得分:4)

我认为你对运营商的定义&lt;是错误的 - 右边(本例中的参数)应该标记为const,它应该是一个const成员函数,例如

    bool operator<(const _pos& other) const{ 

            return this->xi < other.xi; 
    }