C++ 自定义运算符 "-->"

181 阅读2分钟

前言

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 中运用到其身影。