#include <iostream>
template <class T>
class Foo {
public:
T val;
Foo(T _v): val(_v){}
friend std::ostream& operator<< (std::ostream& out, const Foo& A) {
out << A.val;
return out;
}
};
// C++ does not allow partial specialization of function templates,
// so we're using a class template here.
template <typename X, typename Y, bool xLarger>
struct DoPlusImpl // When x is selected
{
typedef Foo<X> result_type;
};
template <typename X, typename Y>
struct DoPlusImpl<X, Y, false> // When y is selected
{
typedef Foo<Y> result_type;
};
template <typename X, typename Y> // Select X or Y based on their size.
struct DoPlus : public DoPlusImpl<X, Y, (sizeof (X) > sizeof (Y))>
{};
// Use template metafunction "DoPlus" to figure out what the type should be.
// (Note no runtime check of sizes, even in nonoptimized builds!)
template <class X, class Y>
typename DoPlus<X, Y>::result_type operator+(const Foo<X>& A, const Foo<Y> & B) {
return typename DoPlus<X, Y>::result_type
(A.val + B.val);
}
int main() {
Foo<double> a(1.5);
Foo<int> b(2);
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << a+b << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGUgPGNsYXNzIFQ+CmNsYXNzIEZvbyB7CnB1YmxpYzoKICAgIFQgdmFsOwogICAgRm9vKFQgX3YpOiB2YWwoX3Ype30KICAgIGZyaWVuZCBzdGQ6Om9zdHJlYW0mIG9wZXJhdG9yPDwgKHN0ZDo6b3N0cmVhbSYgb3V0LCBjb25zdCBGb28mIEEpIHsKICAgICAgICBvdXQgPDwgQS52YWw7CiAgICAgICAgcmV0dXJuIG91dDsKICAgIH0KfTsKCi8vIEMrKyBkb2VzIG5vdCBhbGxvdyBwYXJ0aWFsIHNwZWNpYWxpemF0aW9uIG9mIGZ1bmN0aW9uIHRlbXBsYXRlcywKLy8gc28gd2UncmUgdXNpbmcgYSBjbGFzcyB0ZW1wbGF0ZSBoZXJlLgoKdGVtcGxhdGUgPHR5cGVuYW1lIFgsIHR5cGVuYW1lIFksIGJvb2wgeExhcmdlcj4Kc3RydWN0IERvUGx1c0ltcGwgLy8gV2hlbiB4IGlzIHNlbGVjdGVkCnsKICAgIHR5cGVkZWYgRm9vPFg+IHJlc3VsdF90eXBlOwp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFgsIHR5cGVuYW1lIFk+CnN0cnVjdCBEb1BsdXNJbXBsPFgsIFksIGZhbHNlPiAvLyBXaGVuIHkgaXMgc2VsZWN0ZWQKewogICAgdHlwZWRlZiBGb288WT4gcmVzdWx0X3R5cGU7Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgWCwgdHlwZW5hbWUgWT4gLy8gU2VsZWN0IFggb3IgWSBiYXNlZCBvbiB0aGVpciBzaXplLgpzdHJ1Y3QgRG9QbHVzIDogcHVibGljIERvUGx1c0ltcGw8WCwgWSwgKHNpemVvZiAoWCkgPiBzaXplb2YgKFkpKT4Ke307CgovLyBVc2UgdGVtcGxhdGUgbWV0YWZ1bmN0aW9uICJEb1BsdXMiIHRvIGZpZ3VyZSBvdXQgd2hhdCB0aGUgdHlwZSBzaG91bGQgYmUuCi8vIChOb3RlIG5vIHJ1bnRpbWUgY2hlY2sgb2Ygc2l6ZXMsIGV2ZW4gaW4gbm9ub3B0aW1pemVkIGJ1aWxkcyEpCnRlbXBsYXRlIDxjbGFzcyBYLCBjbGFzcyBZPgp0eXBlbmFtZSBEb1BsdXM8WCwgWT46OnJlc3VsdF90eXBlIG9wZXJhdG9yKyhjb25zdCBGb288WD4mIEEsIGNvbnN0IEZvbzxZPiAmIEIpIHsKICAgICByZXR1cm4gdHlwZW5hbWUgRG9QbHVzPFgsIFk+OjpyZXN1bHRfdHlwZQogICAgICAgICAoQS52YWwgKyBCLnZhbCk7Cn0KCmludCBtYWluKCkgewogICAgRm9vPGRvdWJsZT4gYSgxLjUpOwogICAgRm9vPGludD4gYigyKTsKICAgIHN0ZDo6Y291dCA8PCBhIDw8IHN0ZDo6ZW5kbDsKICAgIHN0ZDo6Y291dCA8PCBiIDw8IHN0ZDo6ZW5kbDsKICAgIHN0ZDo6Y291dCA8PCBhK2IgPDwgc3RkOjplbmRsOwp9Cg==