Search code examples
c++operator-overloadingliteralsoperand

Overloading operators: operand order when using C++ literals


I am writing a class and I got to the point where I can do operations that mix my class type objects and C++ literals, but in one direction only.

here is a simplified code that shows the idea:

#include <iostream>
#include <string>
using namespace std;

class CLS
{
    string str;

public:
    CLS(const char* param)
    {    str = param;   }

    CLS operator+(const CLS& rhs)
    {
        str = str + rhs.str;
        return *this; }

    friend ostream& operator<<(ostream& out, const CLS& rhs);
};

ostream& operator<<(ostream& out, const CLS& rhs)
{
    out << rhs.str;
    return out; }

int main()
{
    CLS a("\n Hello ");
    CLS b("bye!\n\n");

    cout << a + "World!\n\n";

    //cout << "\n Good " + b; /* this is not possible because of the operands order */
}

As you see, I can do something like:

a + "W";

but not,

"W" + a;

As indicated in the last line of the code.

I understand the reason.

The first is equivalent to:

a.operator+("W");

which is covered by my class. However, the second is like,

"W".operator(a);

which is not covered and the literal itself is not an object of a class as I understand. And so, the expression as whole cannot be.

I understand I can create a user defined literals, but this is not what I want to do here. (although I am not sure if they gonna work or not).

I could not find any hint browsing questions I supposed to be related on this site, and I could not get something related to my issue on the net.

My question:

Is there a way that can make either order works?


Solution

  • This code:

    cout << "\n Good " + b; /* this is not possible because of the operands order */
    

    does not work because you made operator+ member (and not const member). If you rewrite it as standalone function (probably friend) then this problem would go away:

    friend 
    CLS operator+(const CLS& lhs, const CLS& rhs)
    {
        CLS r;
        r.str = lhs.str + rhs.str;
        return r; 
    }
    

    if you create additional ctor that accepts const std::string & it would be even simpler:

    friend 
    CLS operator+(const CLS& lhs, const CLS& rhs)
    {
        return CLS( lhs.str + rhs.str );
    }
    

    note, you should rewrite existing constructor this way:

    CLS(const char* param) : str( param )
    {}
    

    it is cleaner and more efficient way