c ++ приведение объединения к одному из его типов членов - PullRequest
4 голосов
/ 21 февраля 2011

Мне кажется совершенно логичным следующее, но это недопустимо в c ++.Объединение не может быть неявно приведено к одному из его типов членов.Кто-нибудь знает вескую причину, почему бы и нет?

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

И кто-нибудь может предложить чистую альтернативу (самое чистое, что я могу придумать, это f(v.i);, который, я признаю, очень чистый, но вышеприведенное просто кажется дажеочиститель)

Ответы [ 5 ]

11 голосов
/ 21 февраля 2011

Соглашаясь с Сумасшедшим Эдди, что для меня это не выглядит лучше, вы можете получить неявное преобразование, определив его:

union u {
    int i;
    char c;
    operator int () const { return i; }
    operator char () const { return c; }
};
4 голосов
/ 21 февраля 2011

Причина, по которой это не доступно неявно (по умолчанию), заключается в том, что это может быть неоднозначным. Совершенно законно иметь более одного члена одного типа, и не было бы никаких оснований отдавать предпочтение одному или другому.

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

u v;
f(v); // which member should be used?
4 голосов
/ 21 февраля 2011

Как компилятор узнает, какой элемент использовать?Необходимо будет отслеживать, какой член был назначен последним, чтобы он знал, к чему конвертировать.Это называется теговым объединением , и хотя язык, безусловно, может указывать такую ​​вещь, это не так (это удержание от C).

Но это нормально, потому что у нас есть boost::variant.Он не только безопаснее и гибче, чем профсоюз, но и более силен.Вы можете применить посетителей к варианту, и он вызовет (посетит) указанную функцию с любым активным членом в данный момент, без дальнейшей работы с пользователем.

1 голос
/ 21 февраля 2011

Кто-нибудь знает вескую причину, почему нет?

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

Лучшая причина, которую я могу придумать.

А кто-нибудь может предложить чистую альтернативу?

Я с Безумным Эдди на этом; f(v.i) настолько «чист», насколько это возможно, не вызывая ошибок программиста. Два дополнительных символа - это приемлемая цена за более надежный код, не так ли?

1 голос
/ 21 февраля 2011

Нет другого синтаксиса, с которым я знаком.Честно говоря, прямой доступ к члену объединения довольно ясен и лаконичен, как есть.

Я предполагаю, что причина неявного приведения заключается в неком правиле, согласно которому технически "неопределенное поведение" писать одному членуобъединение, затем считывание из другого члена.

Неявно приведенный тип может быть не последним записанным.Хотя это прекрасно компилируемый код и он , вероятно, будет работать нормально, компилятор, в принципе, не должен автоматически или неявно делать что-то, противоречащее самим правилам, которые он применяет.

...