template<typename Derived>
struct Op
{
template<typename ScalarType>
friend Derived operator* (ScalarType const& Lambda, Derived Rhs)
{
return Rhs *= Lambda;
}
};
template<typename T>
struct Foo
{
};
template<typename T>
struct Bar : Op<Bar<T> >
{
template<typename U>
Bar operator*= (U)
{
return *this;
}
};
template<typename T>
void operator* (Foo<T>, Bar<T>)
{
}
int main()
{
Foo<int>() * Bar<int>();
}
dGVtcGxhdGU8dHlwZW5hbWUgRGVyaXZlZD4Kc3RydWN0IE9wCnsKCXRlbXBsYXRlPHR5cGVuYW1lIFNjYWxhclR5cGU+CglmcmllbmQgRGVyaXZlZCBvcGVyYXRvciogKFNjYWxhclR5cGUgY29uc3QmIExhbWJkYSwgRGVyaXZlZCBSaHMpCgl7CgkJcmV0dXJuIFJocyAqPSBMYW1iZGE7Cgl9Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpzdHJ1Y3QgRm9vCnsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0cnVjdCBCYXIgOiBPcDxCYXI8VD4gPgp7Cgl0ZW1wbGF0ZTx0eXBlbmFtZSBVPgoJQmFyIG9wZXJhdG9yKj0gKFUpCgl7CgkJcmV0dXJuICp0aGlzOwoJfQp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kdm9pZCBvcGVyYXRvciogKEZvbzxUPiwgQmFyPFQ+KQp7Cn0KCmludCBtYWluKCkKewoJRm9vPGludD4oKSAqIEJhcjxpbnQ+KCk7Cn0=
prog.cpp: In function ‘int main()’:
prog.cpp:33:13: error: ambiguous overload for ‘operator*’ (operand types are ‘Foo<int>’ and ‘Bar<int>’)
Foo<int>() * Bar<int>();
^
prog.cpp:33:13: note: candidates are:
prog.cpp:27:6: note: void operator*(Foo<T>, Bar<T>) [with T = int]
void operator* (Foo<T>, Bar<T>)
^
prog.cpp:5:17: note: Derived operator*(const ScalarType&, Derived) [with ScalarType = Foo<int>; Derived = Bar<int>]
friend Derived operator* (ScalarType const& Lambda, Derived Rhs)
^