代码之家  ›  专栏  ›  技术社区  ›  Navaneeth K N

自定义类型作为map -C++的键

  •  23
  • Navaneeth K N  · 技术社区  · 16 年前

    我正在尝试将自定义类型指定为的键 std::map . 以下是我用作键的类型:

    struct Foo
    {
        Foo(std::string s) : foo_value(s){}
    
        bool operator<(const Foo& foo1) {   return foo_value < foo1.foo_value;  }
    
        bool operator>(const Foo& foo1) {   return foo_value > foo1.foo_value;  }
        
        std::string foo_value;
    };
    

    标准::地图 ,我得到以下错误:

    error C2678: binary '<' : no operator found which takes a left-hand operand of type 'const Foo' (or there is no acceptable conversion) c:\program files\microsoft visual studio 8\vc\include\functional 143
    

    如果我改变主意 struct 对于下面的一个,一切正常:

    struct Foo
    {
        Foo(std::string s) : foo_value(s)   {}
    
        friend bool operator<(const Foo& foo,const Foo& foo1) { return foo.foo_value < foo1.foo_value;  }
    
        friend bool operator>(const Foo& foo,const Foo& foo1) { return foo.foo_value > foo1.foo_value;  }
        
        std::string foo_value;
    };
    

    没有任何更改,只不过运算符重载为 朋友 . 为什么我的第一个代码不起作用?

    4 回复  |  直到 4 年前
        1
  •  32
  •   Matt Davis    15 年前

    我想你需要

    bool operator<(const Foo& foo1) const;
    

    注意 const 在参数之后,这将使“your”(比较中的左侧)对象保持常量。

    之所以只需要一个操作员,是因为它足以实现所需的排序。要回答抽象问题“a必须在b之前吗?”只需知道a是否小于b即可。

        2
  •  3
  •   stefanB    16 年前

    它可能在寻找常量成员运算符(不管正确的名称是什么)。 这项工作(注:const):

    bool operator<(const Foo& foo1) const { return foo_value < foo1.foo_value;}
    

    编辑:删除 operator> 根据我的回答,因为不需要(从问题中复制/粘贴),但它吸引了评论:)

    常数

        3
  •  0
  •   honk    4 年前

    其他答案已经解决了你的问题,但我想提供另一种解决方案。自从 C++11 你可以使用 lambda expression 而不是定义 operator< struct operator> 为映射的构造函数提供lambda表达式具有某些优点:

    • 我发现lambda表达式的声明比运算符的声明更简单,更不容易出错。
    • 结构 要存储在地图中的。
    • 您可以为使用您的地图的不同地图提供不同的比较功能 结构 作为关键。
    • 您仍然可以定义 操作员< 以不同的方式,并将其用于不同的目的。

    结构 简言之:

    struct Foo {
        Foo(std::string s) : foo_value(s) {}
        std::string foo_value;
    };
    

    然后可以按以下方式定义地图:

    int main() {
        auto comp = [](const Foo& f1, const Foo& f2) { return f1.foo_value < f2.foo_value; };
        std::map<Foo, int, decltype(comp)> m({ {Foo("b"), 2}, {Foo("a"), 1} }, comp);
        // Note: To create an empty map, use the next line instead of the previous one.
        // std::map<Foo, int, decltype(comp)> m(comp); 
    
        for (auto const &kv : m)
            std::cout << kv.first.foo_value << ": " << kv.second << std::endl;
    
        return 0;
    }
    

    输出:

    a:1
    b:2

    Code on Ideone