0
#include <stdio.h> 

struct B { int x,y; }; 

struct A : public B { 
    // This whines about "copy assignment operator not allowed in union" 
    //A& operator =(const A& a) { printf("A=A should do the exact same thing as A=B\n"); } 
    A& operator =(const B& b) { printf("A = B\n"); } 
}; 

union U { 
    A a; 
    B b; 
}; 

int main(int argc, const char* argv[]) { 
    U u1, u2; 
    u1.a = u2.b; // You can do this and it calls the operator = 
    u1.a = (B)u2.a; // This works too 
    u1.a = u2.a; // This calls the default assignment operator >:@ 
} 

Есть ли обходной путь, чтобы быть в состоянии сделать это последнюю строку u1.a = u2.a с точно таким же синтаксисом, но это называют operator = (не волнует, если это = (B &) или = (A &)) вместо того, чтобы просто копировать данные? Или неограниченные союзы (не поддерживаемые даже в Visual Studio 2010) - единственный вариант?C++ неограниченного союза обходного

+0

Зачем вам создавать союз, если класс и его потомок? Для чего вам это нужно? – JoshD

+0

Точкой наследования от B является получение «operator =» в структуре, которую может обрабатывать компилятор. Я помещаю потомка в профсоюз, чтобы показать, что вы можете сделать «operator =» членом профсоюза для типа _any_, кроме его собственного ... – Chris

+0

Комментарий к 'u1.a = u2.a;' должен быть предположительно ' // Это вызывает оператор присваивания по умолчанию '... –

ответ

3

C++ does not allow for a data member to be any type that has a full fledged constructor/destructor and/or copy constructor, or a non-trivial copy assignment operator.

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

Вы сбиваете с толку copy assignment operator vs assignment operator здесь. Оператор присваивания копии является особым случаем. В вашем примере A& operator =(const B & b) не классифицируется как оператор присваивания копий, это просто оператор присваивания, а C++ не ограничивает вас тем, что он в классе помещается в объединение. Но когда объект присваивается копированием, оператор вызова копирования (который вы назвали оператором назначения по умолчанию ) все равно будет вызываться.

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

Так что вам нужно придумать альтернативную функцию вместо назначения. Ближе всего было бы использовать какой-то другой оператор, например <<:

выхода
#include <stdio.h> 

struct B { int x, y; }; 

struct A : B 
{ 
    A& operator =(const B& b) { printf("A = B\n"); return *this; } 
}; 

union U { 
    A a; 
    B b; 
}; 

A & operator << (A & lhs, const B & rhs) 
{ 
    printf ("A & operator << (const A & lhs, const B & rhs)\n"); 
    return lhs = rhs; 
} 

int 
main() 
{ 
    U u1, u2; 
    u1.a << u2.b; 
    u1.a << u2.a; 
} 

Это будет следующее:

$ ./test 
A & operator << (const A & lhs, const B & rhs) 
A = B 
A & operator << (const A & lhs, const B & rhs) 
A = B 

На всяком случае, есть unrestricted unions in C++0x.

Надеюсь, это поможет.

+0

Bummer. Объявление его как частного также заставляет компилятор жаловаться. Похоже, я могу переключиться на gcc 4.6. – Chris

+0

gcc 4.6 поддерживает неограниченные объединения, если вы включите поддержку C++ 0x, передав команду '-std = C++ 0x' команде' g ++ '. Вот список функций C++ 0x в gcc 4.6 - http://gcc.gnu.org/gcc-4.6/cxx0x_status.html – 2010-10-07 20:15:13

Смежные вопросы