繁体   English   中英

非protobuf类的protobuf`oneof`功能的C ++实现

[英]C++ implementation of protobuf `oneof` feature for non-protobuf class

protobuf oneof功能很棒。 但它只能当在领域中使用oneof是原始类型或protobuf的消息。 如果我有两个类AB ,它们是由C ++代码而不是protobuf消息定义的,并且我想实现一个类AorB ,例如:

message AorB {
    oneof oneof_name {
        A a = 1;
        B b = 2;
    }
}

我尝试阅读oneof字段的生成的C ++代码,以了解如何实现。 但这很复杂。 有没有简洁的方法来实现这一目标? 还是我可以直接使用的任何模板?

根据您可以使用的C ++版本,您的选择为std::variant ,使用可变参数模板滚动自己或使用union滚动自己。 std::variant已添加到C ++ 17语言中,并且肯定是最容易管理的。 可变参数模板版本比较棘手。

union工作到语言的开始,看起来像这样。

struct MyAorB {
  union {
    A a;
    B b;
  };
  ~MyAorB() { destruct(); }
  MyAorB& operator=(const MyAorB&) = delete;
  MyAorB& operator=(MyAorB&&) = delete;
  MyAorB(const MyAorB&) = delete;
  MyAorB(const MyAorB&&) = delete;
  enum { HOLDS_NONE, HOLDS_A, HOLDS_B } which_one = HOLDS_NONE;
  A& get_A() { assert(which_one == HOLDS_A); return a; }
  B& get_B() { assert(which_one == HOLDS_B); return b; }
  void set_A(A new_a) { which_one = HOLDS_A; destruct(); a = std::move(new_a); }
  void set_B(B new_b) { which_one = HOLDS_B; destruct(); b = std::move(new_b); }
  void destruct() {
    switch (which_one) {
      case HOLDS_A: a.~A(); break;
      case HOLDS_B: b.~B(); break;
      default: break;
    }
  }
};

在某种程度上可能起作用。 不过,还有很多细节可以解决。 它的基本原理是,联合将值放入重叠的内存中,一次仅一个有效,并且访问错误的值是不确定的行为。 重新分配保留值之前,您还需要手动销毁。

我可能错过了某个地方的细节。 我宁愿将其留给std::variant但是如果您需要编写自己的有区别的联合,它将开始类似于上面的代码。

有关变体的更多详细信息,请访问: https : //en.cppreference.com/w/cpp/utility/variant

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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