Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Error operator+ function

Reply
Thread Tools

Error operator+ function

 
 
James Kanze
Guest
Posts: n/a
 
      02-13-2011
On Feb 12, 7:04 pm, Ian Collins <(E-Mail Removed)> wrote:
> On 02/13/11 12:10 AM, James Kanze wrote:


[...]
> >> You have to remove the ambiguity. For starters, making the constructor
> >> from unsigned explicit removes one possible accidental conversion. Then
> >> you can remove the operator + for unsigned. That leaves only one
> >> possible sequence of conversions.


> > But likely not the one he wants.


> How do you know? Considering he doesn't even test the result! In this
> example, it doesn't matter whether operator+(unsigned, int) or
> A:perator+(const A&) is called.


Just guessing, but in general, if you define an operator+ for a
class, you want it to be used when adding values of that class.

> >> You could also remove the remaining operator + and use a free function:


> >> A operator+( const A& a, const A& b )
> >> {
> >> A t(a);
> >> t += b;
> >> return t;
> >> }


> > (For the expression d + 7, where d has type A, and type A has
> > both a constructor taking unsigned, and a conversion operator to
> > unsigned.)


> > How would that remove the ambiguity? You'd still have the two
> > possibilities: convert the A to unsigned, and use integer
> > arithmetic, or convert the int to A, and use the above. The
> > first results in a better match for the first argument, and the
> > second a better match for the second, so the expression is
> > ambiguous.


> Not if the constructor from unsigned is explicit.


If the constructor from unsigned is explicit, then the
expression is unambiguous, regardless of whether the operator is
a member or not; there is only one operator+ which can be
called, and that is the built-in one. The reason for preferring
a non-member is so that 7 + d has the same behavior at the
interface level as d + 7. If d + 7 is legal, and 7 + d isn't,
then you're clearly abusing operator overloading.

--
James Kanze
 
Reply With Quote
 
 
 
 
Öö Tiib
Guest
Posts: n/a
 
      02-14-2011
On Feb 13, 2:33*pm, James Kanze <(E-Mail Removed)> wrote:
> On Feb 12, 6:07 pm, Öö Tiib <(E-Mail Removed)> wrote:
>
> > On Feb 12, 1:10 pm, James Kanze <(E-Mail Removed)> wrote:

>
> * * [...]
>
>
>
>
>
> > > This way, you get exactly what you want. *(Somewhere floating
> > > around I've got a template base class which does this
> > > automatically if you define an A:perator+=(unsigned rhs)
> > > member. *Something like:
> > > * * template< typename DerivedType, typename SecondType >
> > > * * class MixedArithmeticOperators
> > > * * {
> > > * * * * friend DerivedType operator+(
> > > * * * * * * * * DerivedType const& lhs,
> > > * * * * * * * * SecondType const& rhs )
> > > * * * * {
> > > * * * * * * DerivedType result(lhs);
> > > * * * * * * result += rhs;
> > > * * * * * * return result;
> > > * * * * }
> > > * * * * friend DerivedType operator+(
> > > * * * * * * * * SecondType const& lhs,
> > > * * * * * * * * DerivedType const& rhs )
> > > * * * * {
> > > * * * * * * DerivedType result(rhs);
> > > * * * * * * result += lhs;
> > > * * * * * * return result;
> > > * * * * }
> > > * * };
> > > You'd then just derive from MixedArithmeticOperators<A,
> > > unsigned>.

> > Seems good, but isn't it simpler to accept parameter by value
> > if you are otherwise going to copy it anyway? ...

>
> Maybe. *If you like revealing implementation details in the
> interface.


I think it does not reveal the details too intrusively. At least
usage of the interface remains same be it value or const reference.

> Seriously, in this case, you could argue both ways; the fact
> that you copy it here is almost part of the contract (since the
> contract says you use the += operator of DerivedType, and that
> operator requires a non-const object). *On the other hand, why
> deviate from the general rule, especially in an inline
> function, where it can make no possible difference with any
> decent compiler.


My point was that the implementation is slightly simpler because copy
is made when passing the parameter. The possible C++0x optimizations
(moving the value) do not matter that much.

> (The "general" rule, almost universal in coding guidelines, is
> use reference to const for class types, value for all others.
> Arguably, this is premature optimization, and the rule should
> be: use value, unless the profiler says otherwise. *But this
> general rule seems ubiquous, and I suspect that without it, the
> profiler would say otherwise often enough to be more than a
> little bothersome.)
>


Yes, that rule is sort of optimization rule. It is likely made to ease
decision between various ways to pass parameters. It is fine rule in
general but when local copy is made anyway then passing by value is
simpler way to make such copy i think. Prefer simplicity when effect
is same ... it is also sort of omnipresent rule.

> > *template< typename Derived, typename Other >
> > *class MixedArithmeticOperators
> > *{
> > * * *friend Derived operator+( Derived lhs
> > * * * * * * * * * * * * * * *, Other const& rhs )
> > * * *{
> > * * * * *lhs += rhs;
> > * * * * *return lhs;
> > * * *}
> > * * *friend Derived operator+( Other const& lhs
> > * * * * * * * * * * * * * * *, Derived rhs )
> > * * *{
> > * * * * *rhs += lhs;
> > * * * * *return rhs;
> > * * *}
> > *};

>
> A third possiblity---one that I've seen more often than the
> above, is:
>
> * * template< typename DerivedType, typename SecondType >
> * * class MixedArithmeticOperators
> * * {
> * * * * friend DerivedType operator+(
> * * * * * * * * DerivedType const& lhs,
> * * * * * * * * SecondType const& rhs )
> * * * * {
> * * * * * * return DerivedType(lhs) += rhs;
> * * * * }
> * * * * friend DerivedType operator+(
> * * * * * * * * SecondType const& lhs,
> * * * * * * * * DerivedType const& rhs )
> * * * * {
> * * * * * * return DerivedType(rhs) += lhs;
> * * * * }
> * * };
>
> I'll admit that I don't like it too much; I don't like side
> effects in a return statement. *But it is the most succinct.


Yes, it is compacted form of your example.

>
> (BTW: I rather like your formatting, with the comma at the start
> of the line, followed by a space. *I've never been able to
> convince anyone else to use it, however, and of course, I do
> follow the local coding guidelines, always. *Have you ever
> succeeded in getting this style into the coding guidelines?)


Sometimes. Most like it in member initializer list for example. Modern
monitors are so wide that if a line needs breaking then it is perhaps
too complex anyway but most agree that operator at start of line makes
it easier to read. Some just don't care. I would probably like some
"canonical style" of C++. The C++ source in repository would be kept
in that style and individual formatting would be then about
configuring the clients and editors ... just like syntax highlighting
and coloring.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Function versus pointer to function, in context of std::function,huh? Alf P. Steinbach C++ 10 07-27-2011 05:51 AM
Function pointer to void function and int function Giannis Papadopoulos C Programming 5 09-05-2005 09:06 PM
How override ALL function calls? (Is there a "function call function"?) seberino@spawar.navy.mil Python 2 08-01-2005 12:38 PM
write a function such that when ever i call this function in some other function .it should give me tha data type and value of calling function parameter komal C++ 6 01-25-2005 11:13 AM
Passing a C++ object's member function to a C function expecing a function pointer! James Vanns C++ 7 01-21-2004 02:39 AM



Advertisments