我是否必须实现所有 4 个运算符重载才能处理所有 const 和非常量组合?
Should I have to implement all 4 operator overload in order to deal with all const and non-const combinations?
一般背景
我有一个自制的 struct
,我想比较它的两个实例。为了做到这一点,我显然超载了 operator==
所以我将能够这样做。现在,可以使用 0 到 2 个 const
实例和 0 到 2 个非 const
实例调用此运算符。
因为我希望我的运算符 ==
比较 2 个常量,因为它比较 const
和 non-const
的任何可能组合,对我来说最好的应该是只写一个重载可以处理所有可能的组合。但据我所知,我没有找到任何方法。
问题
这是否意味着如果我需要考虑所有可能的组合,我必须写出所有 4 种可能的重载?无论如何我可以避免只用 const
关键字更改编写 4 次相同的函数吗?
具体例子
所以这里是 struct
。它表示计划中的一个对象,由其位置和与其关联的值组成:
struct Foo
{
int x;
int y;
double value;
};
现在假设 2 Foo
相等,如果它们具有相同的值和相同的位置。我有以下运算符:
inline bool operator==(Foo object) // Compare two non-const Foo
{
return (x == object.x) && (y == object.y) && (value == object.value);
}
但是,呃,不幸的是有些 Foo
可以是常量,这意味着我的对象不能按计划移动并且不能改变它们的值。现在我需要检查两个 const Foo
是否可以相等,以及非 const Foo
是否可以等于 const Foo
。
有没有办法做到这一点,但仍然避免编写与第一个函数几乎相同的以下函数?
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);
}
我对c++版本没有任何要求。它可以是 c++17 或 c++20。
如果你有一个非const
Foo
对象,你可以在需要const Foo&
对象的地方使用它,你可以在它上面调用const
方法,所以你应该只有一个重载:
bool operator==(Foo const& object) const {
return (x == object.x) && (y == object.y) && (value == object.value);
}
对于行为不同的特定情况,您只需区分 const
和非 const
重载,具体取决于对象是 const
还是非 const
,例如 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;
您通常希望二元运算符具有非成员函数,必要时使用 friend
。在您的情况下,由于所有成员都是 public,您可以简单地创建一个自由函数(在 struct
之外):
bool operator==(Foo const& lhs, Foo const& rhs) const {
return lhs.x == rhs.x && lhs.y == rhs.y && lhs.value == rhs.vallue;
}
您也可以删除现在有点无关紧要的 inline
修饰符,例如,参见 When should I write the keyword 'inline' for a function/method?.
您还可以检查 What are the basic rules and idioms for operator overloading? 一些关于运算符重载的习语。
没有理由这样做!
只要只是比较,最好总是使用 const references
:
inline bool operator==(const Foo &object)const{
return (x == object.x) && (y == object.y) && (value == object.value);
}
原因是您可以将 const
和 non-const
的地址或引用传递给 const
成员函数,而不是相反。
根据 constness
事项,有时会发生重载。
与大多数二元运算符一样,运算符== 通常应作为单个非成员自由函数实现:
inline bool operator==(const Foo & a, const Foo & b ) {
return a.x == b.x && a.y == b.y && a.value == b.value;
}
一般背景
我有一个自制的 struct
,我想比较它的两个实例。为了做到这一点,我显然超载了 operator==
所以我将能够这样做。现在,可以使用 0 到 2 个 const
实例和 0 到 2 个非 const
实例调用此运算符。
因为我希望我的运算符 ==
比较 2 个常量,因为它比较 const
和 non-const
的任何可能组合,对我来说最好的应该是只写一个重载可以处理所有可能的组合。但据我所知,我没有找到任何方法。
问题
这是否意味着如果我需要考虑所有可能的组合,我必须写出所有 4 种可能的重载?无论如何我可以避免只用 const
关键字更改编写 4 次相同的函数吗?
具体例子
所以这里是 struct
。它表示计划中的一个对象,由其位置和与其关联的值组成:
struct Foo
{
int x;
int y;
double value;
};
现在假设 2 Foo
相等,如果它们具有相同的值和相同的位置。我有以下运算符:
inline bool operator==(Foo object) // Compare two non-const Foo
{
return (x == object.x) && (y == object.y) && (value == object.value);
}
但是,呃,不幸的是有些 Foo
可以是常量,这意味着我的对象不能按计划移动并且不能改变它们的值。现在我需要检查两个 const Foo
是否可以相等,以及非 const Foo
是否可以等于 const Foo
。
有没有办法做到这一点,但仍然避免编写与第一个函数几乎相同的以下函数?
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);
}
我对c++版本没有任何要求。它可以是 c++17 或 c++20。
如果你有一个非const
Foo
对象,你可以在需要const Foo&
对象的地方使用它,你可以在它上面调用const
方法,所以你应该只有一个重载:
bool operator==(Foo const& object) const {
return (x == object.x) && (y == object.y) && (value == object.value);
}
对于行为不同的特定情况,您只需区分 const
和非 const
重载,具体取决于对象是 const
还是非 const
,例如 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;
您通常希望二元运算符具有非成员函数,必要时使用 friend
。在您的情况下,由于所有成员都是 public,您可以简单地创建一个自由函数(在 struct
之外):
bool operator==(Foo const& lhs, Foo const& rhs) const {
return lhs.x == rhs.x && lhs.y == rhs.y && lhs.value == rhs.vallue;
}
您也可以删除现在有点无关紧要的 inline
修饰符,例如,参见 When should I write the keyword 'inline' for a function/method?.
您还可以检查 What are the basic rules and idioms for operator overloading? 一些关于运算符重载的习语。
没有理由这样做!
只要只是比较,最好总是使用 const references
:
inline bool operator==(const Foo &object)const{
return (x == object.x) && (y == object.y) && (value == object.value);
}
原因是您可以将
const
和non-const
的地址或引用传递给const
成员函数,而不是相反。根据
constness
事项,有时会发生重载。
与大多数二元运算符一样,运算符== 通常应作为单个非成员自由函数实现:
inline bool operator==(const Foo & a, const Foo & b ) {
return a.x == b.x && a.y == b.y && a.value == b.value;
}