#include <iostream>
class B;
class A {
double d;
public:
A(double a) : d(a) {}
friend class B;
double operator*(B& b); // auto operator*(B& b) -> decltype(d * B::i) と書けない
};
class B {
int i;
public:
B(int j) : i(j) {}
friend class A;
auto operator*(A& a) -> decltype(i * A::d) {
return i * a.d;
}
};
auto A::operator*(B& b) -> decltype(d * B::i)
{
return d * b.i;
}
template<class T, class U>
auto mul(T x, U y) -> decltype(x * y)
{
return x * y;
}
int main()
{
A a(3.0);
B b(5);
std::cout << mul(a, b) << std::endl;
std::cout << a * b << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKY2xhc3MgQjsKCmNsYXNzIEEgewogIGRvdWJsZSBkOwpwdWJsaWM6CiAgQShkb3VibGUgYSkgOiBkKGEpIHt9CiAgZnJpZW5kIGNsYXNzIEI7CiAgZG91YmxlIG9wZXJhdG9yKihCJiBiKTsgLy8gYXV0byBvcGVyYXRvciooQiYgYikgLT4gZGVjbHR5cGUoZCAqIEI6OmkpIOOBqOabuOOBkeOBquOBhAp9OwoKY2xhc3MgQiB7CiAgaW50IGk7CnB1YmxpYzoKICBCKGludCBqKSA6IGkoaikge30KICBmcmllbmQgY2xhc3MgQTsKICBhdXRvIG9wZXJhdG9yKihBJiBhKSAtPiBkZWNsdHlwZShpICogQTo6ZCkgewogICAgcmV0dXJuIGkgKiBhLmQ7CiAgfQp9OwoKYXV0byBBOjpvcGVyYXRvciooQiYgYikgLT4gZGVjbHR5cGUoZCAqIEI6OmkpCnsKICByZXR1cm4gZCAqIGIuaTsKfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgVT4KYXV0byBtdWwoVCB4LCBVIHkpIC0+IGRlY2x0eXBlKHggKiB5KQp7CiAgcmV0dXJuIHggKiB5Owp9CgppbnQgbWFpbigpCnsKICBBIGEoMy4wKTsKICBCIGIoNSk7CgogIHN0ZDo6Y291dCA8PCBtdWwoYSwgYikgPDwgc3RkOjplbmRsOwogIHN0ZDo6Y291dCA8PCBhICogYiA8PCBzdGQ6OmVuZGw7Cn0=