Multiple suitable operators

M

mathieu

Hi there,

I'd like to know what is the defined behavior for the following (*).
Basically when there is more than one suitable operator, what does the
compiler choose ?

Thanks
-Mathieu

(*)
struct A
{
friend bool operator == (const A & a, const A & b);
A():a(0) {}
private:
bool operator == (const A & aa)
{
return aa.a == a;
}
int a;
};

bool operator == (const A & a, const A & b)
{
return a.a == b.a;
}

int main()
{
A a1;
A a2;
bool b = a1 == a2;
return 0;
}
 
S

Saeed Amrollahi

Hi there,

  I'd like to know what is the defined behavior for the following (*).
Basically when there is more than one suitable operator, what does the
compiler choose ?

Thanks
-Mathieu

(*)
struct A
{
  friend bool operator == (const A & a, const A & b);
  A():a(0) {}
private:
  bool operator == (const A & aa)
    {
    return aa.a == a;
   }
  int a;

};

bool operator == (const A & a, const A & b)
{
    return a.a == b.a;

}

int main()
{
  A a1;
  A a2;
  bool b = a1 ==  a2;
  return 0;



}- Hide quoted text -

- Show quoted text -

Hi Mathieu

Interestingly enough, by compiling your code, you figure out which
function
will be called first.
Your code doesn't compile, because you declare equality operator
member function private.
So, compiler select this one to execute the following code:
bool b = a1 == a2; :)
FYI, in overloaded functions, the function selection process is called
"overload resolution".
In overload resolution, first member candidates are selected, then non-
members.
Please check out section 13.3 of C++ standard document.
BTW, if you want to use both private and public parts, use class
rather than struct.

Regards,
-- Saeed Amrollahi
 
V

Victor Bazarov

mathieu said:
Hi there,

I'd like to know what is the defined behavior for the following (*).
Basically when there is more than one suitable operator, what does the
compiler choose ?

Thanks
-Mathieu

(*)
struct A
{
friend bool operator == (const A & a, const A & b);
A():a(0) {}
private:
bool operator == (const A & aa)
{
return aa.a == a;
}
int a;
};

bool operator == (const A & a, const A & b)
{
return a.a == b.a;
}

int main()
{
A a1;
A a2;
bool b = a1 == a2;
return 0;
}

13.3 is notoriously difficult to read. Here is a hint: consider
'constness' of the first operand of those operators and that of the
object for which you call that operator.

V
 
A

Alf P. Steinbach

* mathieu:
Hi Saeed


Thanks !


Because... ?

It's an established convention to indicate POD type by using 'struct'.

So 'struct' for a non-POD type, except in short examples on Usenet & so on,
communicates the wrong thing to a reader of the code.

However, in C++0x, I'm not sure, it's possible that without your constructor
your class would pass as POD or sd something-somthing-layout, whatever. So
what's good advice today might change tomorrow! :) Or, later...


Cheers & hth.,

- Alf
 
J

James Kanze

The rules are fairly complicated. And sometimes, there is a
tie, and the call is ruled ambiguous (which is an error).
Interestingly enough, by compiling your code, you figure out
which function will be called first. Your code doesn't
compile, because you declare equality operator member function
private.

Note that access is not considered in overload resolution. The
compiler will chose a function (or not) independantly of access
rights; if it then turns out that you don't have the right to
access that function at the call site, you get an error (even if
there were other functions which could have been called that you
could have accessed).
So, compiler select this one to execute the following code:
bool b = a1 == a2; :)
FYI, in overloaded functions, the function selection process
is called "overload resolution". In overload resolution,
first member candidates are selected, then non- members.

No. As Victor pointed out (or at least hinted), the reason the
member function is preferred here is because it takes a
non-const argument on the left side, so it is a better match for
the first argument. If he'd declared the member function const
as well (as he probably should have), the compiler would have
complained that the operator was ambiguous.
Please check out section 13.3 of C++ standard document.

That's easier said than done. It's one of the more complicated
parts of C++.
 
J

James Kanze

* mathieu:

[...]
It's an established convention to indicate POD type by using
'struct'.

Established by whom? I've seen several different conventions --
my own is to declare struct when all of the data members are
public (even if some of the data members are e.g. std::string,
which means that it isn't a POD). I've also seen people
declaring interfaces "struct", when all of the members are
public (albeit pure virtual).
 
A

Alf P. Steinbach

* James Kanze:
* mathieu:
[...]
BTW, if you want to use both private and public parts, use class
rather than struct.
Because... ?
It's an established convention to indicate POD type by using
'struct'.

Established by whom?

Rather by "what". With some caveats a POD can be said to be the C++ equivalent
of a C "struct". The convention I referred follows from that association.

Instead of a style guide, check out discussions about this, e.g.
<url:
http://stackoverflow.com/questions/54585/when-should-you-use-a-class-vs-a-struct-in-c>

I've seen several different conventions --
my own is to declare struct when all of the data members are
public (even if some of the data members are e.g. std::string,
which means that it isn't a POD).

That's an "aggregate". Add a constructor and you have That Thing For Which We
Have No Name. The Nameless Thing, a C++ specific class type.

I've also seen people
declaring interfaces "struct", when all of the members are
public (albeit pure virtual).

Yeah, it's in the nature of conventions that they're not enforced, and that
there can be many contradictory conventions.


Cheers & hth.,

- Alf
 
M

mathieu

13.3 is notoriously difficult to read.  Here is a hint: consider
'constness' of the first operand of those operators and that of the
object for which you call that operator.

Of course... the answer was much simpler.

Thanks
 
J

James Kanze

* James Kanze:
* mathieu:
[...]
BTW, if you want to use both private and public parts, use class
rather than struct.
Because... ?
It's an established convention to indicate POD type by using
'struct'.
Established by whom?
Rather by "what". With some caveats a POD can be said to be
the C++ equivalent of a C "struct". The convention I referred
follows from that association.

I'm not saying it's a bad convention. Just that it's not widely
used.
Instead of a style guide, check out discussions about this, e.g.
<url:http://stackoverflow.com/questions/54585/when-should-you-use-a-class-...>
That's an "aggregate".

I know. But a lot of people (myself included) use the keyword
struct when defining one.
Add a constructor and you have That Thing For Which We Have No
Name. The Nameless Thing, a C++ specific class type.

I've also done that a lot: something starts out as an aggregate,
then it turns out that I don't need aggregate initialization,
but a couple of obvious constructors would be nice. So it stops
being an aggregate, but since all of its data members are still
public, it keeps the keyword struct. In the conventions I
usually use, of course.
Yeah, it's in the nature of conventions that they're not
enforced, and that there can be many contradictory
conventions.

Which is really all I wanted to say. (With regards to the
original example, with, IIRC, private data, I don't know of any
widely used convention that would use struct for it.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,527
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top