Custom types as key for a map - C++

2019-01-14 06:20发布

I am trying to assign a custom type as a key for std::map. Here is the type which I am using as key.

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;
};

When used with std::map, I am getting the following error.

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

If I change the struct like the below, everything worked.

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;
};

Nothing changed except making the operator overloads as friend. I am wondering why my first code is not working?

Any thoughts?

4条回答
倾城 Initia
2楼-- · 2019-01-14 06:52

I suspect you need

bool operator<(const Foo& foo1) const;

Note the const after the arguments, this is to make "your" (the left-hand side in the comparison) object constant.

The reason only a single operator is needed is that it is enough to implement the required ordering. To answer the abstract question "does a have to come before b?" it is enough to know whether a is less than b.

查看更多
来,给爷笑一个
3楼-- · 2019-01-14 06:54

It's probably looking for const member operators (whatever the correct name is). This works (note const):

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

EDIT: deleted operator> from my answer as it was not needed (copy/paste from question) but it was attracting comments :)

Note: I'm 100% sure that you need that const because I compiled the example.

查看更多
迷人小祖宗
4楼-- · 2019-01-14 06:56

Note the const after the arguments, this is to make "your" (the left-hand side in the comparison) object constant.

Could you please elaborate on this? Why if you make the member const (which as far as I know means that it can't change object's state - e.g. modify private variables) guarantees that "your" will be the left-hand side?

查看更多
一纸荒年 Trace。
5楼-- · 2019-01-14 07:04

Could you please elaborate on this? Why if you make the member const (which as far as I know means that it can't change object's state - e.g. modify private variables) guarantees that "your" will be the left-hand side?

I don't yet have the rep to comment on this.

const does not magically ensure that "your" will be the left hand side. The poster was saying that the left hand side (i.e. x in x < y) is the object on which the comparison is being called. Just as you protect y's members from change with the const on the argument to operator<, you also want to protect x's members from change with the const at the end of the method signature.

查看更多
登录 后发表回答