#include <iostream>
using namespace std;
template< class T >
class foo
{
public:
T _value;
foo() : _value() {}
template <class U>
foo(const foo<U>& that) : _value(that.getval()) {}
// I'm sure this it can be done without this being public also;
T getval() const { return _value ; };
foo(const T& that) : _value(that) {}
friend foo& operator +=(foo &lhs,const foo &rhs)
{
lhs._value+=rhs._value;
return lhs;
};
friend std::ostream& operator<<(std::ostream& out, const foo& me){
return out <<me._value;
}
};
template <typename T, typename U>
const foo<T> operator +(foo<T> &lhs,const foo<U> &rhs)
{
foo<T> result(lhs._value+rhs._value);
return result;
}
template <typename T>
const foo<T> operator +(foo<T> &lhs,const T &rhsval)
{
foo<T> result(lhs._value+rhsval);
return result;
}
template <typename T>
const foo<T> operator +(const T &lhsval,foo<T> &rhs)
{
foo<T> result(lhsval+rhs._value);
return result;
}
int main(){
foo< int > f, g;
foo< double > dd;
cout <<f<<endl;
f = f + g;
cout <<f<<endl;
f += 3 ;
cout <<f<<endl;
f = f + 5;
cout <<f<<endl;
f = 7 + f;
cout <<f<<endl;
dd=dd+f;
cout <<dd<<endl;
dd=f+dd;
cout <<dd<<endl;
dd=dd+7.3;
cout <<dd<<endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnRlbXBsYXRlPCBjbGFzcyBUID4KY2xhc3MgZm9vCnsKcHVibGljOgogICBUIF92YWx1ZTsKICAgZm9vKCkgOiBfdmFsdWUoKSB7fQoKICAgdGVtcGxhdGUgPGNsYXNzIFU+CiAgIGZvbyhjb25zdCBmb288VT4mIHRoYXQpIDogX3ZhbHVlKHRoYXQuZ2V0dmFsKCkpIHt9CgogICAvLyBJJ20gc3VyZSB0aGlzIGl0IGNhbiBiZSBkb25lIHdpdGhvdXQgdGhpcyBiZWluZyBwdWJsaWMgYWxzbzsKICAgVCBnZXR2YWwoKSBjb25zdCB7IHJldHVybiBfdmFsdWUgOyB9OyAKCiAgIGZvbyhjb25zdCBUJiB0aGF0KSA6IF92YWx1ZSh0aGF0KSB7fQoKICAgZnJpZW5kIGZvbyYgb3BlcmF0b3IgKz0oZm9vICZsaHMsY29uc3QgZm9vICZyaHMpCiAgICAgIHsKICAgICBsaHMuX3ZhbHVlKz1yaHMuX3ZhbHVlOwogICAgIHJldHVybiBsaHM7CiAgICAgIH07ICAgCiAgIGZyaWVuZCBzdGQ6Om9zdHJlYW0mIG9wZXJhdG9yPDwoc3RkOjpvc3RyZWFtJiBvdXQsIGNvbnN0IGZvbyYgbWUpewogICAgICByZXR1cm4gb3V0IDw8bWUuX3ZhbHVlOwogICB9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgVT4KY29uc3QgZm9vPFQ+IG9wZXJhdG9yICsoZm9vPFQ+ICZsaHMsY29uc3QgZm9vPFU+ICZyaHMpIAogICAgICB7CiAgICAgZm9vPFQ+IHJlc3VsdChsaHMuX3ZhbHVlK3Jocy5fdmFsdWUpOyAKICAgICByZXR1cm4gcmVzdWx0OwogICAgICB9CnRlbXBsYXRlIDx0eXBlbmFtZSBUPgogICBjb25zdCBmb288VD4gb3BlcmF0b3IgKyhmb288VD4gJmxocyxjb25zdCBUICZyaHN2YWwpIAogICAgICB7CiAgICAgZm9vPFQ+IHJlc3VsdChsaHMuX3ZhbHVlK3Joc3ZhbCk7IAogICAgIHJldHVybiByZXN1bHQ7CiAgICAgIH0KdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CiAgIGNvbnN0IGZvbzxUPiBvcGVyYXRvciArKGNvbnN0IFQgJmxoc3ZhbCxmb288VD4gJnJocykgCiAgICAgIHsKICAgICBmb288VD4gcmVzdWx0KGxoc3ZhbCtyaHMuX3ZhbHVlKTsgCiAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgfQoKCmludCBtYWluKCl7CiAgIGZvbzwgaW50ID4gZiwgZzsKICAgZm9vPCBkb3VibGUgPiBkZDsKICAgY291dCA8PGY8PGVuZGw7CiAgIGYgPSBmICsgZzsKICAgY291dCA8PGY8PGVuZGw7CiAgIGYgKz0gMyA7CiAgIGNvdXQgPDxmPDxlbmRsOwogICBmID0gZiArIDU7CiAgIGNvdXQgPDxmPDxlbmRsOwogICBmID0gNyArIGY7IAogICBjb3V0IDw8Zjw8ZW5kbDsgICAgICAKICAgZGQ9ZGQrZjsKICAgY291dCA8PGRkPDxlbmRsOyAgICAgIAogICBkZD1mK2RkOwogICBjb3V0IDw8ZGQ8PGVuZGw7ICAgICAgCiAgIGRkPWRkKzcuMzsKICAgY291dCA8PGRkPDxlbmRsOyAgICAgICAgICAgICAKfQo=