On Monday, 15 October 2012 at 09:33:23 UTC, Maxim Fomin wrote:
---foo.d---
struct A
{
int i;
alias i this;
}
---bar.d---
int opUnary(string T)(A a) { ... }
...
{
++a;
}
-----------
I. i is incremented, opUnary is not called. However opUnary
matches better to the actual type and if it were a method, it
would be called - another special issue in the language which
breaks usual logic. And if you declared opUnary in bar.d when
alias this was absent in foo.d and later added - hijacking also
occurs but now it happens from another side. Bad.
Let's talk about the semantics of the word "hijacking" as it
relates to this discussion. Here's my take on it:
Let type T have some inherent functionality F. That is,
functionality F cannot be removed from T without making changes
to the module file where type T is defined. Then, if some other
functionality F' overrides (replaces and modifies) F, it is said
that F' "hijacks" F.
If I apply this definition to your example, we see that the free
function opUnary in bar.d is *not* part of struct A's inherent
functionality. Therefore, by adding later that alias this in A's
definition, we are *not* hijacking anything.
Furthermore, if that free function opUnary was defined in foo.d
instead, it would be an inherent part of A's functionality. Then,
by adding later that alias this in A's definition, we would be
*changing* A's functionality. But that's not hijacking, because
we're making the change in the module file where A is defined.
That's not hijacking, that's just changing the inherent
functionality of your own user-defined type.