Boost :: visitor多次访问相同的数据类型

时间:2015-03-27 09:23:48

标签: c++ boost

我尝试从协议实现数据结构。为了确保有效负载类型适合所包含的数据,我有一个访问者函数来获取类型。在所有其他数据结构中,变体中使用了不同的类型,期望在有效载荷中。

enum class PayloadType : uint8_t {
    Unsecured = 0,
    Signed = 1,
    Encrypted = 2,
    Signed_External = 3,
    Signed_And_Encrypted = 4
};

typedef ByteBuffer Unsecured;
typedef ByteBuffer Signed;
typedef ByteBuffer Encrypted;
typedef ByteBuffer SignedExternal;
typedef ByteBuffer SignedAndEncrypted;
typedef boost::variant<Unsecured, Signed, Encrypted, SignedExternal, SignedAndEncrypted> Payload;

现在的问题是,访问者中的每个类型都是相同的(例如,Signed是ab ByteBuffer,就像Encrypted是ByteBuffer一样)。

PayloadType get_type(const Payload& payload) {
struct PayloadVisitor : public boost::static_visitor <> {
  void operator()(const Unsecured& unsecured){
      mtype = PayloadType::Unsecured;
  }
  void operator()(const Signed& sign){
      mtype = PayloadType::Signed;
  }
  void operator()(const Encrypted& encrypted){
      mtype = PayloadType::Encrypted;
  }
  void operator()(const SignedExternal& external){
      mtype = PayloadType::Signed_External;
  }
  void operator()(const SignedAndEncrypted& sign){
      mtype = PayloadType::Signed_And_Encrypted;
  }
  PayloadType mtype;
};

PayloadVisitor visit;
boost::apply_visitor(visit, payload);
return visit.mtype;
}

有没有办法让不同类型相互区分?

我发现它有效,如果我将它们放入如下结构:

struct SignedExternal {
    ByteBuffer buf;
}
struct Signed {
    ByteBuffer buf;
}
and so on..

然而,它很长时间使用数据类型。 也许有一种简单的方法来实现这个目标?

2 个答案:

答案 0 :(得分:0)

这里的问题是,您尝试使用typedef来表示它不是:声明一种新类型。 (我认为对于c ++ 11来说可能已经改变了,因为它允许使用typedef&gt; ed模板)。如果有人能够在标准中找到参考,我将不胜感激,但就目前而言,来自cppreference.com

  

typedef-names是现有类型的别名,不是新类型的声明。

您只是通过执行typedef来获取新类型。也许继承可以帮助你,给你真实的&#34;新类型,但我不知道在整个应用程序中这是否是一个好主意。它可能是 - 你的问题很好地符合多态的想法。

通常,c ++是静态类型的,因此使用对象类型作为信息的一部分的想法可能不是最好的。通常,您可能只希望缓冲类具有字段&#34; type&#34;指的是enum,并根据该字段的值进行操作。但这只是穷人的遗产。如果你想拥有可怜的C man继承,那么也要做同样的事情,但是保存一个函数指针&#34;做正确的事情&#34;以及你的缓冲区。

答案 1 :(得分:0)

您可以使用强类型设置

BOOST_STRONG_TYPEDEF(SignedExternal, ByteBuffer);

其中有两个,一个在Bosot Utility中,一个在Boost Serialization中,我记得。

其中一个具有更多功能(比如解除一些操作符,比如我记得的比较/相等)。