【问题标题】:How can I insert custom objects into a std::map?如何将自定义对象插入 std::map?
【发布时间】:2011-11-21 23:37:23
【问题描述】:

我已经阅读了cplusplus.com 上的map::map 参考资料,但我仍然不确定如何让它发挥作用。我要做的就是创建一个如下所示的地图:

std::map<TriSpec, unsigned int> TriSpecMap;

那我想插入如下:

result = TriSpecMap.insert(std::make_pair(triSpecObject, anUnsignedInt));

以下是我的 TriSpec 标头和 .cpp 的简短示例:

//TriSpec.h
#ifndef TRISPEC_H
#define TRISPEC_H
class TriSpec
{
public:
    TriSpec(void);
    ~TriSpec(void);

    unsigned int m_position;
};
bool operator< (const TriSpec& lhs, const TriSpec& rhs);
#endif
//TriSpec.cpp
#include "TriSpec.h"

TriSpec::TriSpec(void){}
TriSpec::~TriSpec(void){}

bool operator< (const TriSpec& lhs, const TriSpec& rhs)
{
    if (lhs.m_position < rhs.m_position) return true;
    else return false;
}

我是否重载了正确的运算符?我使用的功能/格式是否正确?当我查看result.second 时,它始终是true,即使我知道要插入的对象应该已经存在于地图中。

【问题讨论】:

    标签: c++ dictionary stl insert containers


    【解决方案1】:

    我看不出你的代码有任何问题,除了 bool 操作符应该是友元方法(它甚至不能在没有友元关键字的情况下编译):

    bool friend operator< (const TriSpec& lhs, const TriSpec& rhs)
    {
         return (lhs.m_position < rhs.m_position);
    }
    

    然后它按预期工作:

    int main(int argc, _TCHAR* argv[])
    {
        std::map<TriSpec, unsigned int> TriSpecMap;
    
        TriSpec triSpecObject1;
        triSpecObject1.m_position = 1;
    
        TriSpec triSpecObject2;
        triSpecObject2.m_position = 1;
    
        TriSpec triSpecObject3;
        triSpecObject3.m_position = 3;
    
        std::pair<std::map<TriSpec, unsigned int>::iterator, bool> retVal = 
            TriSpecMap.insert(std::make_pair(triSpecObject1, 1));
    
        retVal = TriSpecMap.insert(std::make_pair(triSpecObject2, 1));
    
        retVal = TriSpecMap.insert(std::make_pair(triSpecObject3, 1));
    
        return 0;
    }
    

    第一次插入的结果为真,第二次插入的结果为假,第三次再次为真-应该如此。然后地图容器包含两个对象 - triSpecObject1 和 triSpecObject3。

    【讨论】:

      【解决方案2】:

      看起来它不会编译 - 您的 operator&lt; 在所有情况下都不会返回值。 (编辑:你已经解决了这个问题,谢谢。)你可以简化一下:

      bool operator< (const TriSpec& lhs, const TriSpec& rhs)
       {
            return (lhs.m_position < rhs.m_position);
       } 
      

      由于您没有显示插入地图的完整代码,因此无法说明为什么返回值 .second 总是返回 true。

      【讨论】:

      • 另一个无法编译的原因是 T C::(void) 函数签名(或任何成员函数的正确形式)。
      • @moshbear:为什么不能编译?这不是从 C 继承的“特性”之一吗?
      • 自从这个答案出来后,OP 帖子中的代码已修复。你可能想修改你的答案。
      • 有时我总是忘记,C 的一些相当 hack-ish 的特性使其适用于 C++并且在未来的 C/C++ 版本中不会被弃用。
      【解决方案3】:

      由于C++11,您还可以使用lambda expression,而不是为您的班级提供operator&lt;。因此,您只需两行代码即可创建地图,如下所示:

      int main()
      {
          auto comp = [](const TriSpec& t1, const TriSpec& t2) { return t1.m_position < t2.m_position; };
          std::map<TriSpec, unsigned int, decltype(comp)> TriSpecMap(comp);
      
          TriSpec t1, t2, t3;
          t1.m_position = 1;
          t2.m_position = 3;
          t3.m_position = 5;
      
          auto retVal = TriSpecMap.emplace(t1, 4);
          retVal = TriSpecMap.emplace(t2, 2);
          retVal = TriSpecMap.emplace(t3, 6);
      
          for (auto const &kv : TriSpecMap)
              std::cout << kv.first.m_position << ": " << kv.second << std::endl;
      
          return 0
      }
      

      输出:

      1:4
      3:2
      5:6

      Code on Ideone

      【讨论】:

        猜你喜欢
        • 2020-02-06
        • 2011-05-30
        • 1970-01-01
        • 2019-08-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多