简体   繁体   English

将联盟强制转换为其成员类型之一

[英]Casting a union to one of its member types

I'm stuck with some generated C code which is a bit messy. 我陷入了一些生成的C代码,这有点混乱。 I'm currently wrapping it into a C++11 interface in order not to go insane. 我目前正在将其包装到C ++ 11接口中,以免发疯。

The C code contains tagged unions. C代码包含标记的联合。 I'd love to be able to provide a simple method to read them, something like: 我希望能够提供一种简单的方法来读取它们,例如:

template <typename U, typename T>
T readTaggedUnion(const U & un) {
    return static_cast<T>(un);
}

Is this legal? 这合法吗?

I would also love to be able to do sanity checks on this, but it looks like type_traits doesn't provide much in terms of unions. 我也很乐意对此进行完整性检查,但是看起来type_traits在联合方面没有提供太多帮助。 And all tags for the unions have their own generated types so there's no way to read those in a generic manner. 联合的所有标记都有其自己的生成类型,因此无法以通用方式读取它们。

I have read c++ casting a union to one of its member types but it doesn't help me. 我已经读过c ++将联合强制转换为其成员类型之一,但这对我没有帮助。

Edit: The code I have is generated based on some input files, which can change, and I have no control on those. 编辑:我拥有的代码是根据一些输入文件生成的,这些文件可以更改,而我无法控制这些文件。 I just know how the output will be structured, so I know which parts will always be the same and which depend on the input files. 我只知道输出的结构,因此我知道哪些部分将始终相同,哪些取决于输入文件。

An example of the generated code for a structure named TestChoice which can contain 4 different things inside: 为名为TestChoice的结构生成的代码的示例,其中可以包含4种不同的内容:

/* Dependencies */
typedef enum TestChoice_PR {
    TestChoice_PR_NOTHING,  /* No components present */
    TestChoice_PR_integer,
    TestChoice_PR_optional,
    TestChoice_PR_enm,
    TestChoice_PR_setof
} TestChoice_PR;

/* TestChoice */
typedef struct TestChoice {
    TestChoice_PR present;
    union TestChoice_u {
        INTEGER_t    integer;
        TestOptional_t   optional;
        TestEnumType_t   enm;
        TestSetOf_t  setof;
    } choice;

    /* Context for parsing across buffer boundaries */
    asn_struct_ctx_t _asn_ctx; // This is not relevant
} TestChoice_t;

I'd be tempted to return a boost::variant<Ts...> (or if you can upgrade to C++17, std::variant ). 我很想返回boost::variant<Ts...> (或者如果可以升级到C ++ 17,则为std::variant )。

In any case 任何状况之下

// quick test to ensure we aren't casting from a non-union:
template<class U>
void union_test( U const volatile& ) {
  static_assert( std::is_union< U >::value, "only unions allowed as an argument" );
}
template<class T, class U>
T union_cast( U const& u ) {
  union_test(u);
  using pT = typename std::remove_reference<T>::type;
  return std::forward<T>(*(pT const*)std::addressof(u));
}
template<class T, class U>
T union_cast( U const&& u ) {
  union_test(u);
  using pT = typename std::remove_reference<T>::type;
  return std::forward<T>(*(pT const*)std::addressof(u));
}
template<class T, class U>
T union_cast( U&& u ) {
  union_test(u);
  using pT = typename std::remove_reference<T>::type;
  return std::forward<T>(*(pT*)std::addressof(u));
}

use: 采用:

struct pt {
  int x,y;
};
union x {
  int a;
  double d;
  pt p;
};

void foo( int type, x in ) {
  switch(type) {
    case 0:
      std::cout << union_cast<int>(in) << "\n";
      return;
    case 1:
      std::cout << union_cast<double>(in) << "\n";
      return;
    case 2:
      std::cout << union_cast<pt>(in).x << "," << union_cast<pt>(in).y << "\n";
      return;
  }
}

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

相关问题 c ++将联合转换为其成员类型之一 - c++ casting a union to one of its member types 可以通过强制转换为布局兼容类型来访问私有成员吗? - Can one access private member functions through casting to layout-compatible types? 将NULL指针转换为对象并调用其成员函数之一是否有实际好处? - Is there a practical benefit to casting a NULL pointer to an object and calling one of its member functions? 正确重用联合成员的存储并转换所涉及的指针(对象池) - Correctly reusing storage of a union member and casting the involved pointers (object pool) 铸造工会 - Casting to union 如果不知道其参数类型,如何默认一个特殊成员 function? - How can one default a special member function if one doesn't know its parameter types? 模板化类如何解析在其类型之一上调用的重载非成员函数? - How does a templated class resolve an overloaded non-member function called on one of its types? 联合:从联合的一个数据成员读取以写入另一个 - Union: Reading from one data member of a union to write into another 是否正在访问一个联合中的一个成员,该联合是从具有未定义或未指定的另一个成员集的联合复制的? - Is accessing one member in a union that copied from a union with another member set undefined or unspecified? 将内存投射为联合 - Casting memory to union
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM