#include <iostream>
#include <typeinfo>
using namespace std;
template<typename T1, typename T2>
auto add(T1 l, T2 r) -> decltype(l + r){
return l + r;
}
class C {};
class B {};
class A {
public:
C operator+(const B& b) {
C c;
return c;
}
};
int main() {
// Using add()
A a;
B b;
auto c = add(a, b);
cout << typeid(a).name() << endl;
cout << typeid(b).name() << endl;
cout << typeid(c).name() << endl;
cout << endl;
// Doing the same thing but not on a function
A a2;
B b2;
auto c2 = a2 + b2;
cout << typeid(a2).name() << endl;
cout << typeid(b2).name() << endl;
cout << typeid(c2).name() << endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZWluZm8+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdGVtcGxhdGU8dHlwZW5hbWUgVDEsIHR5cGVuYW1lIFQyPgphdXRvIGFkZChUMSBsLCBUMiByKSAtPiBkZWNsdHlwZShsICsgcil7CiAgICByZXR1cm4gbCArIHI7Cn0KCmNsYXNzIEMge307CgpjbGFzcyBCIHt9OwoKY2xhc3MgQSB7CnB1YmxpYzoKICAgIEMgb3BlcmF0b3IrKGNvbnN0IEImIGIpIHsKICAgICAgICBDIGM7CiAgICAgICAgcmV0dXJuIGM7CiAgICB9Cn07CgoKaW50IG1haW4oKSB7CiAgICAvLyBVc2luZyBhZGQoKQogICAgQSBhOwogICAgQiBiOwogICAgYXV0byBjID0gYWRkKGEsIGIpOwogICAgCiAgICBjb3V0IDw8IHR5cGVpZChhKS5uYW1lKCkgPDwgZW5kbDsKICAgIGNvdXQgPDwgdHlwZWlkKGIpLm5hbWUoKSA8PCBlbmRsOwogICAgY291dCA8PCB0eXBlaWQoYykubmFtZSgpIDw8IGVuZGw7CiAgICBjb3V0IDw8IGVuZGw7CiAgICAKICAgIC8vIERvaW5nIHRoZSBzYW1lIHRoaW5nIGJ1dCBub3Qgb24gYSBmdW5jdGlvbgogICAgQSBhMjsKICAgIEIgYjI7CiAgICBhdXRvIGMyID0gYTIgKyBiMjsKICAgIAogICAgY291dCA8PCB0eXBlaWQoYTIpLm5hbWUoKSA8PCBlbmRsOwogICAgY291dCA8PCB0eXBlaWQoYjIpLm5hbWUoKSA8PCBlbmRsOwogICAgY291dCA8PCB0eXBlaWQoYzIpLm5hbWUoKSA8PCBlbmRsOwp9Cg==