如何在地图中插入结构?

时间:2011-08-18 19:02:25

标签: c++ map

删除给定行的注释后,我在代码中编译错误。我无法将结构插入到地图中,而插入整数很好。如何解决错误?

# include <iostream>
# include <map>

using namespace std;

struct node
{int test;}temp;

int main()
{
    temp.test = 24;
    int test = 30;
    map < node, bool > mymap1;
    map < int, bool > mymap2;
    //mymap1.insert(make_pair(temp, true));
    mymap2.insert(make_pair(test, true));
    return 0;
}

4 个答案:

答案 0 :(得分:11)

对于用作地图键的类型,必须订购。实际上,所有这些意味着必须为类型定义operator<。如果您定义了全局operator<(const node&, const node&),这应该可以正常工作;即,

bool operator<(const node& n1, const node& n2) {
    return n1.test < n2.test;
}

答案 1 :(得分:8)

std :: map的键内部存储在二叉搜索树中。为了在二叉搜索树中存储和搜索密钥,它们必须是可比较的。例如,二元搜索树的要求是左子项的键小于其父项的键,右子项的键大于其父项的键。但是,如果密钥不具有可比性,我们如何判断孩子是否比父母更大或更小?我们不能形成树,因此std :: map不适用于这些类型。

您只需要像这样定义小于运算符:

bool operator<(const node& n1, const node& n2)
{
    return n1.test < n2.test;
}

如果“test”数据成员是私有的,那么它也必须是节点结构的朋友(因为节点当前是结构,所以它现在是公共的)。但是,我可能会这样做:

#include <map>

class node
{
    public:
        int getTest() const { return _test; }
        void setTest(int test) { _test = test; }
    private:
        int _test;
};

bool operator<(const node& n1, const node& n2)
{
    return n1.getTest() < n2.getTest();
}

int main()
{
    std::map<node,bool> foo;
    node n;
    n.setTest(25);

    foo[n] = true;

    return 0;
}

答案 2 :(得分:1)

以下是阅读错误消息的方法:

/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = node]’:
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_tree.h:1141:   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 = node, _Val = std::pair<const node, bool>, _KeyOfValue = std::_Select1st<std::pair<const node, bool> >, _Compare = std::less<node>, _Alloc = std::allocator<std::pair<const node, bool> >]’
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_map.h:469:   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 = node, _Tp = bool, _Compare = std::less<node>, _Alloc = std::allocator<std::pair<const node, bool> >]’
prog.cpp:15:   instantiated from here
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/stl_function.h:230: error: no match for ‘operator<’ in ‘__x < __y’

首先,我们忽略大多数'实例化'行,因为他们只是讨论模板如何扩展。重要的是最后一个,指的是我们的源代码,因为它告诉我们错误被触发的位置。当然,无论如何我们都知道,所以我们也会跳过它。我们也会忽略有问题的库头的路径,因为我们并不关心编译器如何存储它的东西。

stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = node]’:
stl_function.h:230: error: no match for ‘operator<’ in ‘__x < __y’

所以...我们的代码间接调用‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = node]’,或者如果我们实际进行了替换,‘bool std::less<node>::operator()(const node&, const node&) const’。这是一个问题,因为有no match for ‘operator<’ in ‘__x < __y’

__x__ystd::less实现中的变量(您应该可以猜到这么多)。从名称中我们可以猜测(如果我们已经研究过标准库,我们就会知道)std::less是一个模板函数,它比较两个相同类型的东西,并返回第一个是否小于第二

它是如何做到的?当然,使用operator<。所以我们需要做的就是解决问题:它说operator<并不存在被比较的东西,所以我们必须提供它。有什么比较? node,当然。所以我们为我们的班级定义operator<

为什么这样做?这样我们就可以编写接受比较操作作为参数的函数(模板参数或运行时参数 - 但前者更常见),并传递std::less。这就是std::less存在的原因:它将事物比较成一个函数,实际函数更有用。

这有什么关系?因为,就像其他人说的那样,std :: map实际上是以std::less作为参数传递的。它实际上是std::map模板的默认参数,用于比较元素。毕竟,地图界面的一部分是每个键都是唯一的。如果你无法比较它们,你将如何检查键的唯一性?当然,从技术上讲,你只需要比较它们的相同性即可。但事实证明,能够订购密钥可以创建更高效​​的数据结构。 (如果你真的参加了大学关于编程和CS的课程,你就会知道这一点。)

为什么int没有问题?您现在应该可以猜到:operator<已经自然适用于int。但是你必须告诉C ++如何为任何用户类型做这件事,因为你可能还有别的想法。

答案 3 :(得分:0)

C ++ 11

Andrew Rasmussen's answer中所述,std::map的键必须具有可比性。但是,您也可以为地图提供自定义比较对象,而不是为结构定义operator<。此外,由于C++11,您可以使用lambda expression而不是定义比较对象。结果,您可以使代码简短,如下所示:

auto comp = [](const node& n1, const node& n2) { return n1.test < n2.test; };
std::map<node, bool, decltype(comp)> mymap1(comp);

Code on Ideone