Making sure I understand why I had an error (C++)

sweenish

Diamond Member
May 21, 2013
3,656
60
91
I have a Money class, with overloaded multiplication and negative sign operator overloads.

In a different class, I was attempting to store the negative of a product, but I was getting an error about passing 'this' argument. Relevant code and errors follow.

I just want to make sure I understand the issue. It's because my return types are const, so the anonymous const Money object that I return cannot be manipulated by the negative sign.

If I defined a move constructor, and simply returned by value, it would work as I expected it to.

Please let me know how right or wrong that assessment is, and if it's wrong, but the real issue is. I can also upload more code if need be. I don't think I'm completely right, because if it was a const issue, the compiler usually does a better job of telling me so. I'm using g++ 7.3.

Money negative sign overload:
Code:
const Money Money::operator -()
{
        dollars = -dollars;
        cents = -cents;

        return Money(dollars, cents);
}

Relevant Money multiplication overload (These are friend functions):
Code:
const Money operator *(const Money &left, const int right)
{
    int leftPennies = left.makePennies();
    int product = leftPennies * right;

    return Money(product / 100, product % 100);
}

const Money operator *(const int left, const Money &right)
{
    return (right * left);
}

The usage that threw an error:
Code:
// cash is a private data member of my other class
// This is in one of my constructor bodies
cash = -(hotdogSupply * wholesaleHotdogCost);

The error:
Code:
HotdogStand.cpp: In constructor ‘MyAwesomeBusiness::HotdogStand::HotdogStand()’:
HotdogStand.cpp:18:46: error: passing ‘const MyAwesomeBusiness::Money’ as ‘this’ argument discards qualifiers [-fpermissive]
   cash = -(hotdogSupply * wholesaleHotdogCost);
                                              ^
In file included from HotdogStand.hpp:4:0,
                 from HotdogStand.cpp:1:
Money.hpp:22:15: note:   in call to ‘const MyAwesomeBusiness::Money MyAwesomeBusiness::Money::operator-()’
   const Money operator -();
 

Merad

Platinum Member
May 31, 2010
2,586
19
81
Yes, I think you're correct. I'm also fairly sure the unary minus operator is intended to be const, so the signature should be:

const Money Money:perator -() const;

After all, there's no reason to mutate 'this' when you're returning a copy.
 
Reactions: sweenish

sweenish

Diamond Member
May 21, 2013
3,656
60
91
Good tip! I will make that change.

EDIT: Just did a little looking on what's considered best for unary minus between returning a copy and returning a reference, and found out about reference qualifiers. Pretty interesting. I'll definitely be utilizing that in a later project. This one is fine with the single return by value version.

https://stackoverflow.com/questions...e-unary-minus-operator-of-an-rvalue-reference
 
Last edited:

mv2devnull

Golden Member
Apr 13, 2010
1,503
145
106
The problem was not in what you did return, but what you did do, like Merad implied:
Code:
Money::operator -()
{
       dollars = -dollars; // trouble
       cents = -cents;

In use:
Code:
const Money foo;
auto bar = -foo; // error, cannot modify foo

Trivial implementation:
Code:
Money::operator- () const
{
  return Money( -dollars, -cents );
}
The return type of the function can be
Code:
Money
const Money
const Money &
but not non-const reference, for we return a temporary unnamed automatic variable.
 

sweenish

Diamond Member
May 21, 2013
3,656
60
91
Yeah, I did switch my function body to create a new object to return.

I was thinking that even if my unary minus had been correctly implemented from the get-go, then I would have still got the error when trying to take the negative of an expression.

But I put together a little test and it does indeed work the way I would have expected. Good to know. I can usually decrypt the compiler error messages well enough, but this one was throwing me.
 

mv2devnull

Golden Member
Apr 13, 2010
1,503
145
106
Probably due to the unnamed temporary in:
Code:
cash = -(hotdogSupply * wholesaleHotdogCost);

It is similar as in:
Code:
Money cash;
Money cost;
int supply;

auto temp = supply * cost;
cost = -temp; // error
It does not matter whether cost and supply are const or not; the operator* accepts all and spits out const Money. The temp is thus const, and there is an attempt to call the non-const operator- on it.

In your version there is no separate variable 'temp'; only an unnamed temporary Money object. GCC had no words for that.


You were actually lucky: if your operator* would return a non-const Money, then your operator- would have been "ok" and you had had a silent logical error.
 

sweenish

Diamond Member
May 21, 2013
3,656
60
91
The temp is thus const, and there is an attempt to call the non-const operator- on it.

The second part of that sentence is the key I was missing. I thought I had all my types and functions set up properly; obviously I did not.

This was an enlightening discussion. Thank you all very much!
 
sale-70-410-exam    | Exam-200-125-pdf    | we-sale-70-410-exam    | hot-sale-70-410-exam    | Latest-exam-700-603-Dumps    | Dumps-98-363-exams-date    | Certs-200-125-date    | Dumps-300-075-exams-date    | hot-sale-book-C8010-726-book    | Hot-Sale-200-310-Exam    | Exam-Description-200-310-dumps?    | hot-sale-book-200-125-book    | Latest-Updated-300-209-Exam    | Dumps-210-260-exams-date    | Download-200-125-Exam-PDF    | Exam-Description-300-101-dumps    | Certs-300-101-date    | Hot-Sale-300-075-Exam    | Latest-exam-200-125-Dumps    | Exam-Description-200-125-dumps    | Latest-Updated-300-075-Exam    | hot-sale-book-210-260-book    | Dumps-200-901-exams-date    | Certs-200-901-date    | Latest-exam-1Z0-062-Dumps    | Hot-Sale-1Z0-062-Exam    | Certs-CSSLP-date    | 100%-Pass-70-383-Exams    | Latest-JN0-360-real-exam-questions    | 100%-Pass-4A0-100-Real-Exam-Questions    | Dumps-300-135-exams-date    | Passed-200-105-Tech-Exams    | Latest-Updated-200-310-Exam    | Download-300-070-Exam-PDF    | Hot-Sale-JN0-360-Exam    | 100%-Pass-JN0-360-Exams    | 100%-Pass-JN0-360-Real-Exam-Questions    | Dumps-JN0-360-exams-date    | Exam-Description-1Z0-876-dumps    | Latest-exam-1Z0-876-Dumps    | Dumps-HPE0-Y53-exams-date    | 2017-Latest-HPE0-Y53-Exam    | 100%-Pass-HPE0-Y53-Real-Exam-Questions    | Pass-4A0-100-Exam    | Latest-4A0-100-Questions    | Dumps-98-365-exams-date    | 2017-Latest-98-365-Exam    | 100%-Pass-VCS-254-Exams    | 2017-Latest-VCS-273-Exam    | Dumps-200-355-exams-date    | 2017-Latest-300-320-Exam    | Pass-300-101-Exam    | 100%-Pass-300-115-Exams    |
http://www.portvapes.co.uk/    | http://www.portvapes.co.uk/    |