I need to think out these replies a bit more.
operator<op type>(const <class>&) const;
is still binary (it gets a hidden *this added to the function, which is
also the reason why
operator<op type>(const <class>&, const <class>&);
complains, it expects 2 input vars and gets 3
Why doesn't this happen if you do
friend operator<op type>(const <class>&, const <class>&);
Because you tell your class that a function with this prototype has
full access
to the non public parts of your class.
if you do:
class foo {
...
return_type operator op_type (const foo&, const foo&);
you tell the compiler that there is a _member_ function "operator<op
type>" that returns a "return_type" and accepts an implicit "this"
pointer and 2 explicit arguments of type "const foo&". therefor the
compiler will complain because you're declaring a binary operator that
get's passed 3 arguments (1 implicit "this", 2 explicit).
if you do:
class foo {
...
_friend_ return_type operator op_type (const foo&, const foo&);
you tell the compiler that the _free_ function "return_type operator
op_type(..." is a friend of class "foo".
i.e. your allow it access to all protected and private members of "foo".
and since _free_ functions are not members of any class they have no
implicit "this" pointer, and hence the 2 arguments are ok (except for
unary operators of course).
--
in the first case (after you remove the 2nd "const foo&" argument) you'd
have to define the member function like this:
return_type foo::operator op_type (const foo& right)
{
// compare "*this" vs. "right"
...
i.e. qualify the name with "foo::" since the function is a member of
foo. in the second case you don't have to qualify the name (since it's a
_free_ function) and only write:
return_type operator op_type (const foo& left, const foo& right)
{
// compare "left" vs. "right"
...
and finally, if you only need "public" access in your _free_ operator
function, then you can simply delete the whole friend declaration from
the "foo" class - but you need to delete the whole line, not just the
"friend" keyword. if you just delete the "friend" keyword you will
change a "friend declaration" into a "member function declaration" which
are 2 completely different things. they look similar, but they are not.