2.0f * a;
instantiates ::operator*<A>
. Within that function, we have the expression b * a
, which, if you look at the (simplified) types, is A * float
. At this point, the compiler needs to make a choice. Should that *
be the global function ::operator*<float>
(because the right hand argument is float
), or should it be A::operator*
? To us humans, it's clear it should be A::operator*
, but from the compiler's perspective it's not immediately clear.
So what does the compiler do? It first tries to find all the operator*
functions that could be used (after which, it tries to determine exactly which one to use). One of those operator*
functions that could be used is ::operator*<float>
. But wait, what is ::operator*<float>
? It's float *(float, const float&)
! And we can't do that! You can't overload operators for primitive types (imagine the chaos if you overloaded int +(int, int)
so you make 1 + 2
do something totally different from what everyone expected it to do).
At this point, the program is ill-formed. The mere fact that the compiler even tries to instantiate ::operator*<float>
invalidates the program as a whole. So what can we do? Tell the compiler exactly what to do:
template<class T>
T operator*(float a, const T& b)
{
// This prevents the compiler from instantiating ::operator*<float>
return b.operator*(a);
// The above is meant to illustrate how the fix needs to work: it needs
// to avoid instantiating ::operator*<float>. Other methods can be used
// (like SFINAE) that might be more elegant (check out Walter's answer
// in the duplicate: https://stackoverflow.com/a/18596809/1287251), but
// in the end any solution used must avoid ::operator*<float>.
}
struct A{
A operator*(float b) const
{
A a;
return a;
}
};
int main()
{
A a;
2.0f * a;
}
In short, to answer the question: no, the code is not valid. You must prevent the compiler from trying to instantiate ::operator*<float>
.
This is explained by @dyp in the comments and by @TemplateRex in the duplicate question. However, I had to read their responses several times before I understood what they meant. I've tried to simplify things in this answer. If I can improve it, please let me know!