On Mon, Sep 13, 2021 at 06:19:20PM +0000, NonNull via Digitalmars-d-learn wrote: > On Monday, 13 September 2021 at 16:12:34 UTC, H. S. Teoh wrote: > > On Mon, Sep 13, 2021 at 02:12:36PM +0000, NonNull via > > Digitalmars-d-learn wrote: > > > Which operators cannot be overloaded and why not? > > > > Others have already given the list, so I won't repeat that. > > I didn't see unary &. Maybe others are missing. [...]
IIRC, unary & cannot be overloaded for the same reasons &&, ||, and ! cannot be overloaded: it leads to hard-to-understand, hard-to-maintain code. Incidentally, C++ *does* allow overloading of &, ostensibly because some wrapper types might want to use it to become transparent. But one of the consequences of this is that now you need a std::address-of pseudo-operator that *actually* takes an address of something when you *really* mean to take the address of the wrapper object instead of the wrapped object. So & loses its original meaning and has to be replaced by a std:: hack. Which, to me, is abundant proof that overloading & was a bad idea in the first place. // BTW, as an aside, as a example of why every-man-for-himself, wild-wild-west operator overloading in C++ is a bad idea, consider these two lines of C++ code: fun<A, B>(a, b); gun<T, U>(a, b); What do they mean? Ostensibly, these are function calls to two template functions, specifying explicit template arguments. Unfortunately, that is not the case: only *one* of these lines is a template function call, the other is something else altogether. But nobody can tell the difference unless they read the entire context, as shown below. (Incidentally, this example also shows why C++'s choice of template syntax was a poor one.) Compile and run with a C++ compiler to find out what the actual behaviour is. ------- // Totally evil example of why C++ template syntax and free-for-all // operator overloading is a Bad, Bad Idea. #include <iostream> struct Bad { }; struct B { }; struct A { Bad operator,(B b) { return Bad(); } }; struct D { }; struct Ugly { D operator>(Bad b) { return D(); } } U; struct Terrible { } T; struct Evil { ~Evil() { std::cout << "Hard drive reformatted." << std::endl; } }; struct Nasty { Evil operator,(D d) { return Evil(); } }; struct Idea { void operator()(A a, B b) { std::cout << "Good idea, data saved." << std::endl; } Nasty operator<(Terrible t) { return Nasty(); } } gun; template<typename T, typename U> void fun(A a, B b) { std::cout << "Have fun!" << std::endl; } int main() { A a; B b; // What do these lines do? fun<A, B>(a, b); gun<T, U>(a, b); } ------- T -- Your inconsistency is the only consistent thing about you! -- KD