【问题标题】:Overloading [ ] operator for stl map in C++在 C++ 中为 stl map 重载 [ ] 运算符
【发布时间】:2012-11-19 03:03:42
【问题描述】:
class foo{

public:
    int a, b, c;
    double val;

    foo(int a){
        ...
    }

...
}

现在我想做:

map <foo*, double> mymap;

foo fa(2);
foo fb(4);

mymap[fa] = 1.0;
mymap[fb] = 2.0;

显然我得到了 [ ] 未定义类型 foo 的错误。但是我如何重载这个操作符呢?就此而言,我如何获得指向 foo 的指针?因为我假设它没有定义,因为 foo 是一个自定义类

【问题讨论】:

  • “我如何获得指针”应该是您的 C++ 教科书或课程材料的一部分。 “我为什么要指针”是一个完全不同的问题:-)

标签: c++ map


【解决方案1】:

密钥必须是foo* 类型。所以你需要这样写:

mymap[&fa] = 1.0;
mymap[&fb] = 2.0;

但请记住,如果 fafb 是本地对象,那么当您从函数返回时,它们将被销毁。所以你不应该从函数中返回mymap,因为一旦函数返回,用作键的对象就不存在了。

【讨论】:

    【解决方案2】:

    这里不需要超载任何东西。您的地图需要指向foo 的指针,因此您需要将指针传递给foo。你可以像这样修复你的代码:

    mymap[&fa] = 1.0;
    mymap[&fb] = 2.0;
    

    小心您必须绝对确定foo 对象的生存时间与地图一样长或更长,否则后者最终会出现悬空指针。例如,这将以眼泪告终:

    map <foo*, double> mymap;
    
    {
      foo fa(2);
      foo fb(4);
      mymap[&fa] = 1.0;
      mymap[&fb] = 2.0;
    } // fa and fb cease to exist
    
    // state of mymap is messed up here.
    

    【讨论】:

    • 然而,通过引用运算符插入指向本地对象的指针通常是一个非常糟糕的主意。顺便说一句,我知道地图在对象的同一范围内,所以这应该不是问题,但如果使用情况发生变化,则确实需要考虑
    • @emartel 地图和foos 在同一个范围内,因此相当安全。
    • 是的,这就是我编辑评论以指出我知道这一点的原因,但如果 OP 没有意识到,让他知道这一点很重要
    【解决方案3】:

    在地图中保留和使用指向某些本地对象的指针可能极度危险。首先,当对象超出范围时,您可能会通过取消引用 std::map 键来使您的应用程序崩溃。此外,它真的很难使用,而且在大多数情况下不是程序员想要的。在你的情况下:

    auto it = mymap.find(&foo(2))
    

    不会编译并且:

    foo fc(2);
    auto it = mymap.find(&fc);
    

    不会在容器内找到任何值(fa 具有相同的值但不同的指针)。真的是你想要的吗?

    这就是为什么我建议将您的 std::map 重新定义为 std::map&lt;foo, double&gt; mymap;,这将按值保留和比较 foo。要使其工作,您需要实现foo::operator&lt;() 或向std::map 提供您自己的排序算法作为模板参数。第一种情况如下所示:

    class foo {
      int a, b, c;
      double val;
    public:
      foo(int a) {}
      bool operator<(const foo &other) const
      { return a < other.a && b < other.b && c < other.c; }
    };
    
    
    int main()
    {
      std::map<foo, double> mymap;
    
      foo fa(2);
      foo fb(4);
    
      mymap[fa] = 1.0;
      mymap[fb] = 2.0;
    
      auto it = mymap.find(foo(2));
    }
    

    【讨论】:

      猜你喜欢
      • 2012-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-15
      • 2012-03-09
      • 1970-01-01
      • 2012-10-20
      相关资源
      最近更新 更多