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

时间:2011-02-20 21:31:00

标签: c++ casting unions

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

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

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

5 个答案:

答案 0 :(得分:11)

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

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

答案 1 :(得分:4)

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

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

答案 2 :(得分:4)

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

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

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

答案 3 :(得分:1)

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

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

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

答案 4 :(得分:1)

任何人都知道为什么不这样做?

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

我能想到的最好的理由。

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

我和Crazy Eddie在一起; f(v.i)在没有邀请程序员错误的情况下就像“干净”一样。两个额外的字符是可以接受的代价,以获得更强大的代码,不是吗?