#include <iostream>
union Union
{
char c;
short s;
int i;
float f;
double d;
operator char() const { std::cout << "getting char\n"; return c; }
operator short() const { std::cout << "getting short\n"; return s; }
operator int() const { std::cout << "getting int\n"; return i; }
operator float() const { std::cout << "getting float\n"; return f; }
operator double() const { std::cout << "getting double\n"; return d; }
template <typename T> operator T() const { std::cout << "error\n"; T t; return t; }
Union &operator =(char ac) { c = ac; std::cout << "set char\n"; return *this; }
Union &operator =(short as) { s = as; std::cout << "set short\n"; return *this; }
Union &operator =(int ai) { i = ai; std::cout << "set int\n"; return *this; }
Union &operator =(float af) { f = af; std::cout << "set float\n"; return *this; }
Union &operator =(double ad) { d = ad; std::cout << "set double\n"; return *this; }
template <typename T> Union &operator =(T at) { std::cout << "error!\n"; return *this; }
};
template <typename T>
void doSomething(Union a, const Union b)
{
a = static_cast<T>(b);
}
int main(int argc, char **argv)
{
Union a, b;
doSomething<int>(a, b);
doSomething<char>(a, b);
doSomething<char *>(a, b);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdW5pb24gVW5pb24KewogICAgY2hhciBjOwogICAgc2hvcnQgczsKICAgIGludCBpOwogICAgZmxvYXQgZjsKICAgIGRvdWJsZSBkOwoKICAgIG9wZXJhdG9yIGNoYXIoKSBjb25zdCB7IHN0ZDo6Y291dCA8PCAiZ2V0dGluZyBjaGFyXG4iOyByZXR1cm4gYzsgfQogICAgb3BlcmF0b3Igc2hvcnQoKSBjb25zdCB7IHN0ZDo6Y291dCA8PCAiZ2V0dGluZyBzaG9ydFxuIjsgcmV0dXJuIHM7IH0KICAgIG9wZXJhdG9yIGludCgpIGNvbnN0IHsgc3RkOjpjb3V0IDw8ICJnZXR0aW5nIGludFxuIjsgcmV0dXJuIGk7IH0KICAgIG9wZXJhdG9yIGZsb2F0KCkgY29uc3QgeyBzdGQ6OmNvdXQgPDwgImdldHRpbmcgZmxvYXRcbiI7IHJldHVybiBmOyB9CiAgICBvcGVyYXRvciBkb3VibGUoKSBjb25zdCB7IHN0ZDo6Y291dCA8PCAiZ2V0dGluZyBkb3VibGVcbiI7IHJldHVybiBkOyB9CiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gb3BlcmF0b3IgVCgpIGNvbnN0IHsgc3RkOjpjb3V0IDw8ICJlcnJvclxuIjsgVCB0OyByZXR1cm4gdDsgfQoKICAgIFVuaW9uICZvcGVyYXRvciA9KGNoYXIgYWMpIHsgYyA9IGFjOyBzdGQ6OmNvdXQgPDwgInNldCBjaGFyXG4iOyByZXR1cm4gKnRoaXM7IH0KICAgIFVuaW9uICZvcGVyYXRvciA9KHNob3J0IGFzKSB7IHMgPSBhczsgc3RkOjpjb3V0IDw8ICJzZXQgc2hvcnRcbiI7IHJldHVybiAqdGhpczsgfQogICAgVW5pb24gJm9wZXJhdG9yID0oaW50IGFpKSB7IGkgPSBhaTsgc3RkOjpjb3V0IDw8ICJzZXQgaW50XG4iOyByZXR1cm4gKnRoaXM7IH0KICAgIFVuaW9uICZvcGVyYXRvciA9KGZsb2F0IGFmKSB7IGYgPSBhZjsgc3RkOjpjb3V0IDw8ICJzZXQgZmxvYXRcbiI7IHJldHVybiAqdGhpczsgfQogICAgVW5pb24gJm9wZXJhdG9yID0oZG91YmxlIGFkKSB7IGQgPSBhZDsgc3RkOjpjb3V0IDw8ICJzZXQgZG91YmxlXG4iOyByZXR1cm4gKnRoaXM7IH0KICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPiBVbmlvbiAmb3BlcmF0b3IgPShUIGF0KSB7IHN0ZDo6Y291dCA8PCAiZXJyb3IhXG4iOyByZXR1cm4gKnRoaXM7IH0KfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgp2b2lkIGRvU29tZXRoaW5nKFVuaW9uIGEsIGNvbnN0IFVuaW9uIGIpCnsKICBhID0gc3RhdGljX2Nhc3Q8VD4oYik7Cn0KCmludCBtYWluKGludCBhcmdjLCBjaGFyICoqYXJndikKewogICAgVW5pb24gYSwgYjsKICAgIAogICAgZG9Tb21ldGhpbmc8aW50PihhLCBiKTsKICAgIGRvU29tZXRoaW5nPGNoYXI+KGEsIGIpOwogICAgZG9Tb21ldGhpbmc8Y2hhciAqPihhLCBiKTsKICAgIAogICAgcmV0dXJuIDA7Cn0K