前言
C++非常的自由,自由到可以重定义运行符操作的含义,那么,在有些时候,可以组合出一些奇奇怪怪的操作。
这些操作实际运用价值不多,但是有时候可以派上用场,比如今天要介绍的如何自定义一个运算符叫做 "-->"
自定义运算符
首先,这个运算符可以被拆分为 - - > 或者 -- > 两种方式,我将采用第二种方式来重新组合一下该运算符。
下面是这个类的一个基础定义
class Node {
Node *next;
public:
Node() { next = nullptr; }
};
然后在这个的基础上,重载 -- 运算符,使其返回一个中间类型,比如TNode
class Node {
Node *next;
class TNode {
Node *self;
public:
explicit TNode(Node *now) : self(now) {}
};
public:
Node() { next = nullptr; }
TNode operator--(int) { return TNode{this}; }
};
此时 ,我们重载中间类型的 operator> 将其和一个Node进行连接
这样就可以变得非常灵活的。
class Node {
Node *next;
class TNode {
Node *self;
public:
explicit TNode(Node *now) : self(now) {}
void operator>(Node *prev) { prev->next = self; }
void operator>(Node &prev) { prev.next = self; }
};
public:
Node() { next = nullptr; }
TNode operator--(int) { return TNode{this}; }
};
此时,我们就可以对其进行 a --> b 这种操作符链接操作了。
这里,我假设 --> 操作是一个链表的连接操作
现在,稍稍加一点模板通用上去
template <typename T> class Node {
T value;
Node<T> *next;
class TNode {
Node<T> *self;
public:
explicit TNode(Node<T> *now) : self(now) {}
void operator>(Node<T> *prev) { prev->next = self; }
void operator>(Node<T> &prev) { prev.next = self; }
};
public:
explicit Node(T v): value(v) { next = nullptr; }
TNode operator--(int) { return TNode{this}; }
static Node<T> *Next(Node<T> *self) { return self->next; }
static T Value(Node<T> *self) { return self->value; }
};
下面是对应的测试代码
int main() {
Node<int> a{1}, b{2}, c{3}, d{4};
d --> c;
c --> b;
b --> a;
auto p = &a;
while (p != nullptr) {
std::cout << Node<int>::Value(p) << std::endl;
p = Node<int>::Next(p);
}
return 0;
}
总结
上述代码将会输出 1 - 4的序列,我选取的例子是一个链表,其实这个的正确用法应该是 图的边连接
是不是会更加详细一点,也会清晰一些。
更多的用途可以在 DAG 中运用到其身影。