C++ 如何在重载运算符中引用当前结构?
我有一个结构,我想通过定义<,>,=运算符来定义它的相对顺序。实际上,在我的顺序中不会有任何相等,所以如果一个结构不比另一个小,它会自动变大 我这样定义了第一个操作符:C++ 如何在重载运算符中引用当前结构?,c++,struct,operators,operator-overloading,C++,Struct,Operators,Operator Overloading,我有一个结构,我想通过定义,=运算符来定义它的相对顺序。实际上,在我的顺序中不会有任何相等,所以如果一个结构不比另一个小,它会自动变大 我这样定义了第一个操作符: struct MyStruct{ ... ... bool operator < (const MyStruct &b) const {return (somefancycomputation);} }; this->operator<( b ); struct MyStruct{ ... ...
struct MyStruct{
...
...
bool operator < (const MyStruct &b) const {return (somefancycomputation);}
};
this->operator<( b );
struct MyStruct{
...
...
布尔运算符<(const MyStruct&b)const{return(somefancycomputation);}
};
现在我想基于这个操作符定义其他操作符,比如我想写的操作符
bool operator > (const MyStruct &b) const {return !(self<b);}
bool操作符>(const MyStruct&b)const{return!(selfself is*此
)
也就是说,这个
是指向当前对象的指针,因此您需要取消对它的引用以获得实际对象。重载运算符只是一个成员函数,尽管具有奇特的语法。
您可以明确地这样称呼它:
struct MyStruct{
...
...
bool operator < (const MyStruct &b) const {return (somefancycomputation);}
};
this->operator<( b );
这个->操作符这是指向当前对象的指针。因此(正如@Dave Hinton所说)您必须取消对它的引用。但是,还有另一个选项
两种选择:
return !(*this<b)
or
return (!this->operator<(b))
return!(*this运算符
实际上,在我的顺序中不会有任何相等,所以如果一个结构不比另一个小,它会自动变大
这是个问题。C++操作(和许多算法)需要a,(除此之外)意味着<代码> x==x < /代码>适用于任何<代码> x>代码>。更一般地说:
not (x < y) and not (y < x)
对于任何x
和y
。换句话说:您很可能必须为您的结构定义某种等式才能与任何常规算法一起工作。如果您提供了操作符我与Tom/Dave的意见一致,我可以直接编写以下内容:
return !(*this<b);
这意味着对以下各项略有改进:
模板
等级可比{
公众:
布尔运算符!=(常量派生和rhs)常量
{return!(静态_cast(*this)=rhs);}
布尔运算符=(常量派生和rhs)常量
{return!(静态_cast(*this) bool operator@genesys扩展到Dave的观点,您将希望将代码编写为类似“bool operator>(const MyStruct&b)const{return!(*这个)向上投票。另一种可能性是创建一个比较两个给定结构a和B的函数。您确定要吗通常,一个将二进制运算符定义为自由函数而不是成员。这样,当隐式转换开始发挥作用时,两个参数的行为都相同;在第二个结构上进行隐式转换,但不是首先是令人不安的。尽管有一些限制条件,但很多事情仍然会起作用。std::sort
会起作用,尽管你自然无法控制“等价”值的顺序。你仍然可以设置和映射,但自然地,一旦你有了一个值,你就不能放置一个“等价”集合“集合中的条目(但您可以使用multiset
和multimap
)。像find
和equal\u range
这样的东西是注定要失败的。字符串弱顺序并不意味着总顺序,或者等价(w.r.t顺序)不意味着相等,或者换句话说,不(x
并不一定意味着x==y
。它必须认为不是(x
。@Charles,“弱”不是意味着两个元素在排序上可能是等价的吗?我想你所说的是“偏序”而不是“弱序”?IIRC,偏序是我认为偏序将集合划分成链,如果你以某种任意方式将它们端到端连接起来,可以将它们扩展成完整的顺序,以及严格的弱序(或总预序)将集合划分为一系列等价集合,如果对每个等价集合施加任意顺序,这些等价集合可以扩展为一个总顺序。恐怕这组宏会让我有点不舒服。是的,我也不喜欢它,一直在用一个类的简单继承来代替它,该类具有==和<定义为纯虚拟。性能mance有点弱,但可读性很差better@Elemental:您可以同时获得(简单性和速度)通过使用CRTP。另外,基于operator@Elemental:哦,比较应该返回bool
,而不是int
!是的-您的模板解决方案非常出色,RHS const&是一个重要的改进。另一个帖子我希望有10张投票给…我想补充一下操作谢谢你的回答。我很抱歉这个问题,但是你能解释一下非成员和成员的区别是什么,为什么要选择第一个吗?谢谢:)是的,提供一个命名函数并重用它是一种更易读的方法。
return !operator<(b);
#define CREATE_SYMETRIC_ORDINAL_OPERATORS(Type) \
int operator !=(Type X) {return !((*this)==X); } \
int operator <(Type X) {return !((*this)>=X); } \
int operator >=(Type X) {return (((*this)>X)||((*this)==X)); } \
int operator <=(Type X) {return (((*this)<X)||((*this)==X)); }
class Comparable {
public:
int operator ==(Comparable B);
int operator >(Comparable B);
CREATE_SYMETRIC_OPERATORS(Comparable);
};
template< class Derived >
class Comparable {
public:
bool operator !=(const Derived& rhs) const
{return !( static_cast<Derived&>(*this) == rhs ); }
bool operator <(const Derived& rhs) const
{return rhs < static_cast<Derived&>(*this); }
bool operator >=(const Derived& rhs) const
{return !( static_cast<Derived&>(*this) < rhs ); }
bool operator <=(const Derived& rhs) const
{return !( static_cast<Derived&>(*this) > rhs ); }
};
struct MyStruct : public Comparable<MyStruct> {
bool operator ==(const MyStruct & rhs) const
{return /* whatever */; }
bool operator <(const MyStruct & rhs) const
{return /* whatever */; }
};