3

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?

Kamal Zidan
  • 474
  • 2
  • 9
  • 2
    Binary operators like `+` should generally be free functions, not members, in which case the problem goes away, as suitable conversions can be performed on both the left and right hand operands.. –  Jun 14 '17 at 19:59

2 Answers2

4

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

Slava
  • 43,454
  • 1
  • 47
  • 90
2

You can add a global function:

inline CLS operator+(const char *lhs, const CLS& rhs)
{
    return CLS(lhs) + rhs;
}
Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • `CLS operator+(const CLS &lhs, const CLS& rhs)` is enough as there is not explicit constructor that accepts `const char *` – Slava Jun 14 '17 at 20:02