复杂的map以及实际应用中应该注意点

1.复杂的map,key和value都是结构体,并且是结构体中变量含有类对象

头文件内容如下:

注意:运算符“<”需要重构(这里涉及到map是二叉树),重载时别忘了两个const,不要直接return true或者false,如果是结构体或者类进行 “!=”比较也需要重构“!=”

class cKey
{
public:
    cKey(int i, string strB):m_iKA(i), m_strKB(strB){}
    ~cKey(){}
    bool operator < (const cKey &other) const
    {
        if (m_iKA != other.m_iKA)
        {
            return m_iKA < other.m_iKA;
        }
        return m_strKB < other.m_strKB;
    }
    cKey &operator = (const cKey &other)
    {
        m_iKA = other.m_iKA;
        m_strKB = other.m_strKB;
        return *this;
    }
public:
    int m_iKA;
    string m_strKB;
};

struct stMultiKey
{
    int m_iKeyA;
    string m_strKeyB;
    cKey m_cKeyC;
    stMultiKey(int i, string strB, cKey &keyC):m_iKeyA(i), m_strKeyB(strB), m_cKeyC(keyC){}
    bool operator < (const stMultiKey &other) const
    {
        if (m_iKeyA != other.m_iKeyA)
        {
            return m_iKeyA < other.m_iKeyA;
        }
        if (m_strKeyB != other.m_strKeyB)
        {
            return m_strKeyB < other.m_strKeyB;
        }
        return m_cKeyC < other.m_cKeyC;
    }
    stMultiKey &operator = (const stMultiKey &other)
    {
        m_iKeyA = other.m_iKeyA;
        m_strKeyB = other.m_strKeyB;
        m_cKeyC = other.m_cKeyC;
        return *this;
    }
};


class cValue
{
public:
    cValue(){}
    cValue(int i, string strB):m_iVA(i), m_strVB(strB){}
    ~cValue(){}
    bool operator < (const cValue &other) const
    {
        if (m_iVA != other.m_iVA)
        {
            return m_iVA < other.m_iVA;
        }
        return m_strVB < other.m_strVB;
    }
    cValue &operator = (const cValue &other)
    {
        m_iVA = other.m_iVA;
        m_strVB = other.m_strVB;
        return *this;
    }
public:
    int m_iVA;
    string m_strVB;
};
struct stMultiValue
{
    int m_iValueA;
    string m_strValueB;
    cValue m_cValueC;
    stMultiValue(){}
    stMultiValue(int i, string strB, cValue &valueC):m_iValueA(i), m_strValueB(strB), m_cValueC(valueC){}
    bool operator < (const stMultiValue &other) const
    {
        if (m_iValueA != other.m_iValueA)
        {
            return m_iValueA < other.m_iValueA;
        }
        if (m_strValueB != other.m_strValueB)
        {
            return m_strValueB < other.m_strValueB;
        }
        return m_cValueC < other.m_cValueC;
    }
    stMultiValue &operator = (const stMultiValue &other)
    {
        m_iValueA = other.m_iValueA;
        m_strValueB = other.m_strValueB;
        m_cValueC = other.m_cValueC;
        return *this;
    }
};

typedef map<stMultiKey, stMultiValue> MultiMap;

内容:(使用pair和make_pair的方式如下都有)

void Print(MultiMap & tmpMap)
{
    MultiMap::iterator it = tmpMap.begin();
    for (;it != tmpMap.end(); it++)
    {
        cout<<"----------key----------"<<endl;
        cout<<"m_iKeyA:"<<it->first.m_iKeyA<<" m_strKeyB:"<<it->first.m_strKeyB.c_str()<<" m_iKA:"<<it->first.m_cKeyC.m_iKA<<" m_strKB:"<<it->first.m_cKeyC.m_strKB.c_str()<<endl;
        cout<<"----------value----------"<<endl;
        cout<<"m_iValueA:"<<it->second.m_iValueA<<" m_strValueB:"<<it->second.m_strValueB.c_str()<<" m_iVA:"<<it->second.m_cValueC.m_iVA<<" m_strKB:"<<it->second.m_cValueC.m_strVB.c_str()<<endl;
        cout<<"=================================="<<endl;
    }
}

int main()
{
    MultiMap tmpMap;
    cKey key0(1,string("123"));
    cKey key1(2,string("234"));
    cKey key2(3,string("345"));

    cValue value0(11, string("111"));
    cValue value1(22, string("222"));
    cValue value2(33, string("333"));

    stMultiKey multikey0(1, string("121"), key0);
    stMultiKey multikey1(2, string("232"), key1);
    stMultiKey multikey2(3, string("343"), key2);

    stMultiValue multivalue0(1, string("111"), value0);
    stMultiValue multivalue1(2, string("222"), value1);
    stMultiValue multivalue2(3, string("333"), value2);
    pair<stMultiKey, stMultiValue> tmpIndex0(multikey0, multivalue0);
    pair<stMultiKey, stMultiValue> tmpIndex1(multikey1, multivalue1);

    tmpMap.insert(tmpIndex0);
    tmpMap.insert(tmpIndex1);
    tmpMap.insert(make_pair(multikey2, multivalue2));

    Print(tmpMap);
    return 0;
}

运行结果如下:

----------key----------
m_iKeyA:1 m_strKeyB:121 m_iKA:1 m_strKB:123
----------value----------
m_iValueA:1 m_strValueB:111 m_iVA:11 m_strKB:111
==================================
----------key----------
m_iKeyA:2 m_strKeyB:232 m_iKA:2 m_strKB:234
----------value----------
m_iValueA:2 m_strValueB:222 m_iVA:22 m_strKB:222
==================================
----------key----------
m_iKeyA:3 m_strKeyB:343 m_iKA:3 m_strKB:345
----------value----------
m_iValueA:3 m_strValueB:333 m_iVA:33 m_strKB:333
==================================

2.更改成下标方式

例如我在map不打算使用insert特性,我需要的是下标的效果,应该如果更改呢

insert和下表的区别参考:map下标的实现以及下表和插入的区别-CSDN博客

错误示范:

void Print(MultiMap & tmpMap)
{
    MultiMap::iterator it = tmpMap.begin();
    for (;it != tmpMap.end(); it++)
    {
        cout<<"----------key----------"<<endl;
        cout<<"m_iKeyA:"<<it->first.m_iKeyA<<" m_strKeyB:"<<it->first.m_strKeyB.c_str()<<" m_iKA:"<<it->first.m_cKeyC.m_iKA<<" m_strKB:"<<it->first.m_cKeyC.m_strKB.c_str()<<endl;
        cout<<"----------value----------"<<endl;
        cout<<"m_iValueA:"<<it->second.m_iValueA<<" m_strValueB:"<<it->second.m_strValueB.c_str()<<" m_iVA:"<<it->second.m_cValueC.m_iVA<<" m_strKB:"<<it->second.m_cValueC.m_strVB.c_str()<<endl;
        cout<<"=================================="<<endl;
    }
}

int main()
{
    MultiMap tmpMap;
    cKey key0(1,string("123"));
    cKey key1(2,string("234"));
    cKey key2(3,string("345"));

    cValue value0(11, string("111"));
    cValue value1(22, string("222"));
    cValue value2(33, string("333"));

    stMultiKey multikey0(1, string("121"), key0);
    stMultiKey multikey1(2, string("232"), key1);
    stMultiKey multikey2(3, string("343"), key2);

    stMultiValue multivalue0(1, string("111"), value0);
    stMultiValue multivalue1(2, string("222"), value1);
    stMultiValue multivalue2(3, string("333"), value2);
    pair<stMultiKey, stMultiValue> tmpIndex0(multikey0, multivalue0);
    pair<stMultiKey, stMultiValue> tmpIndex1(multikey1, multivalue1);
    tmpMap.insert(tmpIndex0);
    tmpMap.insert(tmpIndex1);
    tmpMap[multikey2] = multivalue2;

    Print(tmpMap);
    return 0;
}

编译不通过:

root@ubuntu:/home/sulier/work/C++11/MapTest/MultiMap# g++ -o MultiMap MultiMap.cpp -std=c++11
In file included from /usr/include/c++/5/bits/stl_map.h:63:0,
                 from /usr/include/c++/5/map:61,
                 from ../../base.h:3,
                 from ../base.h:1,
                 from MultiMap.h:1,
                 from MultiMap.cpp:1:
/usr/include/c++/5/tuple: In instantiation of ‘std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>) [with _Args1 = {const stMultiKey&}; long unsigned int ..._Indexes1 = {0ul}; _Args2 = {}; long unsigned int ..._Indexes2 = {}; _T1 = const stMultiKey; _T2 = stMultiValue]’:
/usr/include/c++/5/tuple:1161:63:   required from ‘std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) [with _Args1 = {const stMultiKey&}; _Args2 = {}; _T1 = const stMultiKey; _T2 = stMultiValue]’
/usr/include/c++/5/ext/new_allocator.h:120:4:   required from ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = std::pair<const stMultiKey, stMultiValue>; _Args = {const std::piecewise_construct_t&, std::tuple<const stMultiKey&>, std::tuple<>}; _Tp = std::_Rb_tree_node<std::pair<const stMultiKey, stMultiValue> >]’
/usr/include/c++/5/bits/alloc_traits.h:530:4:   required from ‘static void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = std::pair<const stMultiKey, stMultiValue>; _Args = {const std::piecewise_construct_t&, std::tuple<const stMultiKey&>, std::tuple<>}; _Tp = std::_Rb_tree_node<std::pair<const stMultiKey, stMultiValue> >; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<std::_Rb_tree_node<std::pair<const stMultiKey, stMultiValue> > >]’
/usr/include/c++/5/bits/stl_tree.h:529:32:   required from ‘void std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_construct_node(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<const stMultiKey&>, std::tuple<>}; _Key = stMultiKey; _Val = std::pair<const stMultiKey, stMultiValue>; _KeyOfValue = std::_Select1st<std::pair<const stMultiKey, stMultiValue> >; _Compare = std::less<stMultiKey>; _Alloc = std::allocator<std::pair<const stMultiKey, stMultiValue> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const stMultiKey, stMultiValue> >*]’
/usr/include/c++/5/bits/stl_tree.h:546:21:   required from ‘std::_Rb_tree_node<_Val>* std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_create_node(_Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<const stMultiKey&>, std::tuple<>}; _Key = stMultiKey; _Val = std::pair<const stMultiKey, stMultiValue>; _KeyOfValue = std::_Select1st<std::pair<const stMultiKey, stMultiValue> >; _Compare = std::less<stMultiKey>; _Alloc = std::allocator<std::pair<const stMultiKey, stMultiValue> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Link_type = std::_Rb_tree_node<std::pair<const stMultiKey, stMultiValue> >*]’
/usr/include/c++/5/bits/stl_tree.h:2170:33:   required from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_emplace_hint_unique(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator, _Args&& ...) [with _Args = {const std::piecewise_construct_t&, std::tuple<const stMultiKey&>, std::tuple<>}; _Key = stMultiKey; _Val = std::pair<const stMultiKey, stMultiValue>; _KeyOfValue = std::_Select1st<std::pair<const stMultiKey, stMultiValue> >; _Compare = std::less<stMultiKey>; _Alloc = std::allocator<std::pair<const stMultiKey, stMultiValue> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const stMultiKey, stMultiValue> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::const_iterator = std::_Rb_tree_const_iterator<std::pair<const stMultiKey, stMultiValue> >]’
/usr/include/c++/5/bits/stl_map.h:483:8:   required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = stMultiKey; _Tp = stMultiValue; _Compare = std::less<stMultiKey>; _Alloc = std::allocator<std::pair<const stMultiKey, stMultiValue> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = stMultiValue; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = stMultiKey]’
MultiMap.cpp:46:18:   required from here
/usr/include/c++/5/tuple:1172:70: error: no matching function for call to ‘stMultiValue::stMultiValue()’
         second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
                                                                      ^
In file included from MultiMap.cpp:1:0:
MultiMap.h:83:2: note: candidate: stMultiValue::stMultiValue(int, std::__cxx11::string, cValue&)
  stMultiValue(int i, string strB, cValue &valueC):m_iValueA(i), m_strValueB(strB), m_cValueC(valueC){}
  ^
MultiMap.h:83:2: note:   candidate expects 3 arguments, 0 provided
MultiMap.h:78:8: note: candidate: stMultiValue::stMultiValue(const stMultiValue&)
 struct stMultiValue
        ^
MultiMap.h:78:8: note:   candidate expects 1 argument, 0 provided

其实是需要增加默认构造函数,其中key部分(结构体stMultiKey相关的)不需要,但是value部分(结构体stMultiValue相关的)需要,而且不管是结构体还是类都需要如下:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值