Перегрузка операторов: порядок операндов при использовании литералов C++

Я пишу класс, и я дошел до того, что могу выполнять операции, которые смешивают объекты типа моего класса и литералы С++, но только в одном направлении.

вот упрощенный код, который показывает идею:

#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 */
}

Как видите, я могу сделать что-то вроде:

a + "W";

но нет,

"W" + a;

Как указано в последней строке кода.

Я понимаю причину.

Первый эквивалентен:

a.operator+("W");

который покрывается моим классом. Тем не менее, второй, как,

"W".operator(a);

который не покрыт, а сам литерал не является объектом класса, как я понимаю. Так вот, выражения в целом быть не может.

Я понимаю, что могу создавать пользовательские литералы, но это не то, что я хочу делать здесь. (хотя я не уверен, будут ли они работать или нет).

Я не смог найти никаких подсказок, просматривая вопросы, которые, как я предполагал, были связаны с этим сайтом, и я не мог найти что-то, связанное с моей проблемой в сети.

Мой вопрос:

Есть ли способ заставить любой порядок работать?


person Kamal Zidan    schedule 14.06.2017    source источник
comment
Бинарные операторы, такие как +, обычно должны быть свободными функциями, а не членами, и в этом случае проблема исчезает, поскольку подходящие преобразования могут выполняться как для левого, так и для правого операнда.   -  person    schedule 14.06.2017


Ответы (2)


Этот код:

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

не работает, потому что вы сделали operator+ членом (а не постоянным членом). Если вы перепишете его как отдельную функцию (вероятно, друга), то эта проблема исчезнет:

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

если вы создадите дополнительный ctor, который принимает const std::string &, это будет еще проще:

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

обратите внимание, вы должны переписать существующий конструктор следующим образом:

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

это более чистый и эффективный способ

person Slava    schedule 14.06.2017

Вы можете добавить глобальную функцию:

inline CLS operator+(const char *lhs, const CLS& rhs)
{
    return CLS(lhs) + rhs;
}
person Chris Dodd    schedule 14.06.2017
comment
CLS operator+(const CLS &lhs, const CLS& rhs) достаточно, так как нет явного конструктора, который принимает const char * - person Slava; 14.06.2017