繁体   English   中英

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

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

以下似乎对我来说是完全符合逻辑的,但是无效的c ++。 联合不能隐式地转换为其中一个成员类型。 任何人都知道一个很好的理由吗?

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

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

虽然同意Crazy Eddie认为它对我来说看起来不那么好,但实际上你可以通过定义它来获得隐式转换:

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

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

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

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

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

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

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

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

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

任何人都知道一个很好的理由吗?

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

我能想到的最好的理由。

任何人都可以建议一个干净的选择?

我跟Crazy Eddie在一起; f(vi)在没有引发程序员错误的情况下就像“干净”一样。 两个额外的字符是可以接受的代价,以支付更强大的代码,不是吗?

暂无
暂无

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

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