简体   繁体   English

c ++将联合转换为其成员类型之一

[英]c++ casting a union to one of its member types

The following seems perfectly logical to me, but isn't valid c++. 以下似乎对我来说是完全符合逻辑的,但是无效的c ++。 A union cannot be implicitly cast to one of it's member types. 联合不能隐式地转换为其中一个成员类型。 Anyone know a good reason why not? 任何人都知道一个很好的理由吗?

union u {
  int i;
  char c;
}
function f(int i) {
}
int main() {
  u v;
  v.i = 6;
  f(v);
}

And can anyone suggest a clean alternative (the cleanest I can come up with is f(vi); , which I admit is very clean, but the above just seems even cleaner) 任何人都可以建议一个干净的替代品(我能想到的最干净的是f(vi);我承认它非常干净,但上面看起来更干净)

While agreeing with Crazy Eddie that it doesn't look that better to me you can actually get an implicit conversion by defining it: 虽然同意Crazy Eddie认为它对我来说看起来不那么好,但实际上你可以通过定义它来获得隐式转换:

union u {
    int i;
    char c;
    operator int () const { return i; }
    operator char () const { return c; }
};

How would the compiler know which member to use? 编译器如何知道使用哪个成员? It would need to keep track of which member was last assigned so it knows what to convert to. 它需要跟踪最后分配的成员,以便知道要转换的内容。 This is called a tagged union , and while it's certainly possible for the language to specify such a thing, that's not the case (it's a hold-over from C). 这被称为标记联合 ,虽然语言当然可以指定这样的东西,但情况并非如此(它是来自C的保留)。

But that's okay, because we have boost::variant . 但那没关系,因为我们有boost::variant Not only is it safer and more flexible than a union, it's more powerful. 它不仅比工会更安全,更灵活,而且功能更强大。 You can apply visitors to the variant, and it'll call (visit) the specified function with whichever member is currently active, with no further work from the user. 您可以将访问者应用于变体,它将使用当前处于活动状态的成员调用(访问)指定的函数,而无需用户进一步处理。

The reason why this isn't available implicitly (by default) is that it can be ambiguous. 隐式(默认情况下)不可用的原因是它可能不明确。 It's completely legal to have more than one member with the same type, and there would be no reason to prefer one or the other. 拥有多个具有相同类型的成员是完全合法的,并且没有理由偏好其中一个。

union u
{
    char c;
    TCHAR t;
    wchar_t w;
    int i;
};
void f(TCHAR);

u v;
f(v); // which member should be used?

There is no different syntax I am familiar with. 我熟悉的语法没有不同。 To be honest, accessing the union member directly is rather clear and concise as is. 说实话,直接访问工会成员是相当清晰和简洁的。

I assume the reason there is no implicit casting is because of some rule whereby it's technically "undefined behavior" to write to one member of a union, then read from another member. 我假设没有隐式转换的原因是因为某些规则从技术上将“未定义的行为”写入一个联合的一个成员,然后从另一个成员读取。

The implicitly casted type may not be the last one written to. 隐式转换类型可能不是最后写入的类型。 While it's perfectly compilable code and it would probably work fine, the compiler, in principle, should not automatically or implicitly do something that is against the very rules it enforces. 虽然它是完全可编译的代码并且它可能工作正常,但编译器原则上不应该自动或隐式地执行违反其强制执行的规则的操作。

Anyone know a good reason why not? 任何人都知道一个很好的理由吗?

function f(char c) {
    doStuff(c);
}

Best reason I can think of. 我能想到的最好的理由。

And can anyone suggest a clean alternative? 任何人都可以建议一个干净的选择?

I'm with Crazy Eddie on this one; 我跟Crazy Eddie在一起; f(vi) is as "clean" as it gets without inviting programmer errors. f(vi)在没有引发程序员错误的情况下就像“干净”一样。 Two extra characters is an acceptable price to pay for more robust code, no? 两个额外的字符是可以接受的代价,以支付更强大的代码,不是吗?

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

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