Search code examples
c++castingoperators

Why the overloaded+ operator cannot be used with a primitive type static_cast to a class?


I'm just starting to dive into the depths of C++. Recently I came across a task to create a bMoney class that will store some monetary value. At the same time, the class must have overloaded operators +, -, * and /. Also, this class must have a constructor that can be used when casting types.

Here's my code with all operators prototypes.

сlass bMoney {
  private:
    long double money;
    
  public:
    explicit bMoney(long double _money = 0.0L) noexcept : money(_money) {};

    bMoney operator+(bMoney &other) const;
    bMoney operator-(bMoney &other) const;
    bMoney operator*(long double times) const;
    bMoney operator/(long double times) const;
};

However, in the process of testing the code, I encountered an interesting error. Here is my code:

bMoney bm1(1.0);
long double ld = 2.0
bMoney bm2 = bm1 + static_cast<bMoney>(ld); //here's the error

I am warned that there is no + operator corresponding to such operators (bMoney + bMoney). However, this warning disappeared as soon as I removed the argument reference in the + operator. Why is this happening? I think it has something to do with static_cast, but still can't figure it out. If you can, please help me

I tried doing static_cast<bMoney>(&ld), but it didn't help. I'm just starting to understand pointers and references, so I'm a little afraid of them.


Solution

  • static_cast creates a prvalue(a temporary object) while your operator+ expects a mutable lvalue - due to bMoney& argument. prvalues cannot bind to mutable lvalue references. When you remove the reference specifier the prvalue is directly initialized into the argument via copy-elision. On the other hand, const lvalue references are able to bind to rvalues. So the usual practice of declaring operator arguments as const lvalue references can eliminate the problem.

    By the way, this is not called diving into C++. This is basic modern C++ material; but those dinosaur instructors in formal academia are are too ignorant to teach you the right stuff. Get yourself a book titled "Modern C++" and published well after 2011. What is perceived as basic/advanced by the average developer is often the opposite of reality. The most basic things in modern C++ are the most recent ones, while most of the stuff before C++11 is advanced. Raw pointers are expert, smart pointers are intermediate, but STL containers and ranges are beginner level.