简体   繁体   中英

Should I have to implement all 4 operator overload in order to deal with all const and non-const combinations?

General context

I have a self-made struct and I want to compare two instance of it. In order to do that I obviously overload the operator== so I will be able to do so. Now, this operator may be called with 0 to 2 const instances and 0 to 2 non- const instances.

As I want my operator == to compare 2 const as it compare any possible combination of const and non-const , the best for me should be to write only one overload which can deal with all possible combination. But as far as I know, I didn't find any way to do so.

Question

Does that mean that if I need to consider all possible combination, I have to write all 4 possible overloads ? Is there anyway I can avoid to write 4 times the same function only with const keywords changing ?


Specific example

So here is the struct . It represents an object on a plan, and consists of its position and a value associated to it:

struct Foo
{
    int x;
    int y;
    double value;
};

Now let's say 2 Foo are equal if they have the same value and the same position. I have the following operator:

inline bool operator==(Foo object) // Compare two non-const Foo
{
    return (x == object.x) && (y == object.y) && (value == object.value);
}

But, eww, unlucky some Foo can be constants, meaning that my objects can't move on the plan and can't change their value. And now I need to check if two const Foo can be equals and if a non- const Foo can be equal to a const Foo .

Is there anyway I can do that but still avoid to write those following functions which are almost the same as the first one ?

inline bool operator==(const Foo &object) // Compare a non-const Foo with a const Foo
{
    return (x == object.x) && (y == object.y) && (value == object.value);
}

inline bool operator==(const Foo &object) const // Compare two const Foo
{
    return (x == object.x) && (y == object.y) && (value == object.value);
}

inline bool operator==(Foo object) const // Compare a const Foo with a non-const Foo
{
    return (x == object.x) && (y == object.y) && (value == object.value);
}

I don't have any requirements on c++ version. It can ever be c++17 or c++20.

Operator==, like most binary operators, should normally be implemented as a single, non-member, free function:

 inline bool operator==(const Foo & a, const Foo & b ) {
       return a.x == b.x && a.y == b.y && a.value == b.value;
 }

If you have a non- const Foo object, you can use it where const Foo& object are expected, and you can call const -method on it, so you should only have one overload:

bool operator==(Foo const& object) const {
    return (x == object.x) && (y == object.y) && (value == object.value);
}

You only needs to differentiate const and non- const overloads for specific cases where the behavior is different depending if the object is const or non- const , eg, for operator[] :

// You want to return a reference on non-const object and a const-reference
// on const object, so you need both overloads.
X& operator[](std::size_t);
const X& operator[](std::size) const;

You usually want to have non-member functions for binary operators, with friend if necessary. In your case, since all members are public, you can simply create a free function (outside the struct ):

bool operator==(Foo const& lhs, Foo const& rhs) const {
    return lhs.x == rhs.x && lhs.y == rhs.y && lhs.value == rhs.vallue;
}

You can also drop that inline modifier which is kind of irrelevant nowadays, see, eg, When should I write the keyword 'inline' for a function/method? .

You can also check What are the basic rules and idioms for operator overloading? for some idioms regarding operator overloading.

There is no reason to do so!

As long as it is just comparison then it is preferred always to use const references :

  inline bool operator==(const Foo &object)const{
        return (x == object.x) && (y == object.y) && (value == object.value);
  }
  • The reason is you can pass the address or reference of const and non-const to a const member function but not the contrary.

  • There are some cases when overloading depending on constness matters.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM