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

发布于 2024-10-18 10:39:54 字数 266 浏览 3 评论 0原文

以下对我来说似乎完全符合逻辑,但不是有效的 C++。联合不能隐式转换为其成员类型之一。有人知道为什么不这样做的充分理由吗?

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

任何人都可以提出一个干净的替代方案(我能想到的最干净的是 f(vi);,我承认它非常干净,但上面的看起来更干净)

The following seems perfectly logical to me, but isn't valid 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(v.i);, which I admit is very clean, but the above just seems even cleaner)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

辞慾 2024-10-25 10:39:54

虽然同意 Crazy Eddie 的观点,即它对我来说看起来并没有那么好,但实际上您可以通过定义它来获得隐式转换:

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

While agreeing with Crazy Eddie that it doesn't look that better to me you can actually get an implicit conversion by defining it:

union u {
    int i;
    char c;
    operator int () const { return i; }
    operator char () const { return c; }
};
半世蒼涼 2024-10-25 10:39:54

之所以不能隐式使用(默认情况下),是因为它可能不明确。拥有多个相同类型的成员是完全合法的,并且没有理由偏爱其中之一。

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

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

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?
狠疯拽 2024-10-25 10:39:54

编译器如何知道要使用哪个成员?它需要跟踪最后分配的成员,以便知道要转换为什么。这称为标记联合,虽然语言当然有可能指定这样的东西,但事实并非如此(它是 C 的保留)。

但这没关系,因为我们有 boost::variant< /代码>。它不仅比工会更安全、更灵活,而且更强大。您可以将访问者应用于变体,它将使用当前处于活动状态的成员调用(访问)指定的函数,而无需用户进行进一步的操作。

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).

But that's okay, because we have 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.

迷雾森÷林ヴ 2024-10-25 10:39:54

没有我熟悉的不同语法。说实话,直接访问工会成员是相当清晰和简洁的。

我认为没有隐式转换的原因是由于某些规则,从技术上讲,写入联合体的一个成员,然后从另一个成员读取,在技术上是“未定义的行为”。

隐式转换的类型可能不是最后写入的类型。虽然它是完全可编译的代码并且可能可以正常工作,但原则上编译器不应自动或隐式执行违反其强制执行规则的操作。

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.

千と千尋 2024-10-25 10:39:54

有人知道为什么不这样做的好理由吗?

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

我能想到的最好的理由。

有人能提出一个干净的替代方案吗?

我支持 Crazy Eddie 的这个方案; f(vi) 非常“干净”,不会引发程序员错误。为了获得更健壮的代码,两个额外的字符是可以接受的代价,不是吗?

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; f(v.i) is as "clean" as it gets without inviting programmer errors. Two extra characters is an acceptable price to pay for more robust code, no?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文