doubt on - C++ FAQ Lite - Item [14.5]

  • Thread starter subramanian100in
  • Start date
S

subramanian100in

In

http://www.parashift.com/c++-faq-lite/friends.html#faq-14.5

the following is mentioned:

(member functions don't allow promotion of the left hand argument,
since that would change the class of the object that is the recipient
of the member function invocation)

I do not understand the part "since that would change the class of the
object that is the recipient of the member function invocation"

Kindly explain with an example.

Thanks
V.Subramanian
 
V

Victor Bazarov

In

http://www.parashift.com/c++-faq-lite/friends.html#faq-14.5

the following is mentioned:

(member functions don't allow promotion of the left hand argument,
since that would change the class of the object that is the recipient
of the member function invocation)

I do not understand the part "since that would change the class of the
object that is the recipient of the member function invocation"

Kindly explain with an example.

What book are you reading that doesn't explain operator overloading?

struct A {
A(int) {}
A operator+(A const&) const { return A(0); }
};

int main() {
A a(42);

a + 77; // Figures that it needs to call A::eek:perator+ from 'a'
// Promotes '77' to another 'A' (the right operand)

33 + a; // promote '33' to A? Leave '33' as is?
// Where to look for 'operator+'?
}

V
 
P

peter koch

In

http://www.parashift.com/c++-faq-lite/friends.html#faq-14.5

the following is mentioned:

(member functions don't allow promotion of the left hand argument,
since that would change the class of the object that is the recipient
of the member function invocation)

I do not understand the part "since that would change the class of the
object that is the recipient of the member function invocation"

Kindly explain with an example.

Thanks
V.Subramanian

I believe I should quote some more of the FAQ as it makes your
question clearer:

"Sometimes friends are syntactically better (e.g., in class Fred,
friend functions allow the Fred parameter to be second, while members
require it to be first). Another good use of friend functions are the
binary infix arithmetic operators. E.g., aComplex + aComplex should be
defined as a friend rather than a member if you want to allow aFloat +
aComplex as well (member functions don't allow promotion of the left
hand argument, since that would change the class of the object that is
the recipient of the member function invocation)."

It simply means that with a binary infix operator such as +, *, / or
-, if you declare them as memberfunctions they cant be called with
anything than class members:

complex aComplex;
float aFloat;
....
aFloat + aComplex will now not compile because that would require
promotion of the aFloat variable, and that is not allowed for the
reasons stated. You would have to rewrite the expression as
complex(aFloat) + aComplex.
Having the operator as a friend will allow the expression above
without the explicit conversion.

/Peter
 
S

subramanian100in

What book are you reading that doesn't explain operator overloading?

struct A {
A(int) {}
A operator+(A const&) const { return A(0); }

};

int main() {
A a(42);

a + 77; // Figures that it needs to call A::eek:perator+ from 'a'
// Promotes '77' to another 'A' (the right operand)

33 + a; // promote '33' to A? Leave '33' as is?
// Where to look for 'operator+'?

}

V
--

In the expression 33 + a, since the type of 'a' is known as
A, why can't 33 be converted to a temporary object of type A and the
expression evaluated accordingly ?

Kindly clarify.

Thanks
V.Subramanian
 
V

Victor Bazarov

In the expression 33 + a, since the type of 'a' is known as
A, why can't 33 be converted to a temporary object of type A and the
expression evaluated accordingly ?

Why should the compiler convert 33 to A and not 'a' to a pointer, say?

V
 
D

Daniel T.

In the expression 33 + a, since the type of 'a' is known as
A, why can't 33 be converted to a temporary object of type A and the
expression evaluated accordingly ?

Kindly clarify.

I'm not an expert at this sort of thing, but I think it is a parser
issue.

The parser finds the token '33' and then the token '+', then it has to
identify all op+ that can apply to an int and finds a nice list of types
for the next token that doesn't not include anything of type A, nor
anything convertible from type A.

33 + A; would work if the type A has an operator int() for example,
because then the compiler would convert A into an int and perform the
calculation.
 
V

Victor Bazarov

Daniel said:
I'm not an expert at this sort of thing, but I think it is a parser
issue.

The parser finds the token '33' and then the token '+', then it has to
identify all op+ that can apply to an int and finds a nice list of
types for the next token that doesn't not include anything of type A,
nor anything convertible from type A.

Well... The compiler looks up all applicable functions that might fit
the bill, so to speak. There *could* be

void operator+(double, A const&);

defined which would cause '33' to be converted to 'double'. However,
[over.match.oper]/3 says that in the situation like the one in my
example, since the left operand is not of class type, the *member*
candidates *are not considered*. So, no conversion of '33' to 'A'
is going to apply to add 'A::eek:perator+' to the list of candidates.
33 + A; would work if the type A has an operator int() for example,
because then the compiler would convert A into an int and perform the
calculation.

Right. But that happens _after_ the compiler picks the built-in op+
as the only candidate function.

V
 
P

pauldepstein

What book are you reading that doesn't explain operator overloading?
...

From the quoted website excerpt, I don't see why you would expect that
the OP (obviously inexperienced) would automatically know to research
the concept called "operator overloading." Nor do I think it is
reasonable to expect people to refrain from posting until they have
thoroughly digested a book on c++. Not sure what the purpose behind
your question is but the assumption that the OP is not reading a book
which discusses operator overloading is clearly unwarranted. Just
hasn't arrived at that part of the text and had no basis on which to
decide to look for that phrase in the index.

Paul Epstein
 
V

Victor Bazarov

From the quoted website excerpt, I don't see why you would expect that
the OP (obviously inexperienced) would automatically know to research
the concept called "operator overloading." Nor do I think it is
reasonable to expect people to refrain from posting until they have
thoroughly digested a book on c++. Not sure what the purpose behind
your question is but the assumption that the OP is not reading a book
which discusses operator overloading is clearly unwarranted. Just
hasn't arrived at that part of the text and had no basis on which to
decide to look for that phrase in the index.

Paul Epstein

It's not reasonable to expect people to refrain from posting, period.
It's reasonable to expect people to put more emphasis on learning C++
from books instead of web sites or newsgroups. Unfortunately that is
sometimes the case. Learning from books (like learning from web sites
and other sources) is possible if the sources are decent/credible. I
just wanted to know what book (as the primary source of information)
the OP was using. You seem to have a problem with that. The FAQ in
question describes/mentions defining operator+, for which the term is
"operator overloading", and anyone who has attempted to define some
operator for their class should know that. Do you not agree?

V
 
J

Jim Langston

In the expression 33 + a, since the type of 'a' is known as
A, why can't 33 be converted to a temporary object of type A and the
expression evaluated accordingly ?

Take, for instance, something like
int main() {
Foo a(42);
Bar a(68);

a + b;
}

If what you were suggesting could take place, then how would the compiler
know if it should convert b to Foo or a to Bar? There has to be some rule
to state which will take place, which is what you are running into. The
right hand side is converted to the left hand side, not vice versa.
Otherwise
a + b;
could produce a Foo or a Bar. If you try to make exceptions like, well,
unless the RHS can't be converted to the LHS then try to convert the LHS to
the RHS, but that would quickly become a nightmare when things were
converted willy nilly.
 
P

pauldepstein

It's not reasonable to expect people to refrain from posting, period.
It's reasonable to expect people to put more emphasis on learning C++
from books instead of web sites or newsgroups. Unfortunately that is
sometimes the case. Learning from books (like learning from web sites
and other sources) is possible if the sources are decent/credible. I
just wanted to know what book (as the primary source of information)
the OP was using. You seem to have a problem with that. The FAQ in
question describes/mentions defining operator+, for which the term is
"operator overloading", and anyone who has attempted to define some
operator for their class should know that. Do you not agree?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask- Hide quoted text -

- Show quoted text -

I stand by everything I said in my earlier posting. When you say "I
just wanted to know what book (as the primary source of information)
the OP was using," you misrepresent your own earlier posting. In
particular your word "just" is inaccurate. Not only did you want to
know about the OP's book -- you also wanted to imply that the OP's
current book (if existent) must be crap because it must omit
discussion of overloading. I gave a good explanation of why this
assumption of yours was unwarranted. You are correct that _if_ you
had instead asked "What book are you using to learn c++?" there would
be no reason for me to have "a problem with that." But your question
was very different.

Re "anyone who has attempted to define some operator for their class
should know that", I disagree with you again. It's wrong to judge
what another person "should know" in this context. What is obvious to
one person might not be obvious to another.

Paul Epstein
 
J

James Kanze

The real question goes beyond operator overloading.
In the expression 33 + a, since the type of 'a' is known as A,
why can't 33 be converted to a temporary object of type A and
the expression evaluated accordingly ?

The simple answer is because the standard does not consider such
conversions when trying to match the object on which a member
function is called. I've already posted several times why this
is so---in the general case, it more or less violates the whole
idea behind what member functions are designed for. The case of
an overloaded binary operator may be an exception in this
regard, but only because the operator you are emulating doesn't
require an lvalue as operand. You certainly wouldn't want a
temporary for something like +=. The basic rule is that the
semantics of the built-in operators aren't taken into
consideration for user defined operators (you probably wouldn't
like it if the compiler considered operator+ commutative on a
string), and you can't overload on lvalue-ness; the current
rules do allow a choice: you can make the operator a member, and
reject any implicit conversions which introduce a new object, or
make it a free function, and accept them. It's not perfect, but
it's far better than nothing.
 

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,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top