mami
mami

Reputation: 129

Identifying the call context / usage when invoking C++ operator overloading

Whether what I want is bad-practice or not, I wonder if one can make a distinction between the following cases:

MyType A, B, C;  

Case1:  
    B  << A;    
Case2:
    C << (B << A);

What i want in Case1 is that B is MODIFIED such that it is concatenated with A. In Case2 on the other hand, I want that B is NOT modified but instead a temporary object equivalent to 'B concatenated with A' be returned (and C is modified and concatenated with that temp object).

Is this possible? If so what should be the operator overloading syntax and variants in C++? I tried r-value versions of operators RHS params; and const/non-const overloads; and also & / && post-fixing the method to discriminate LHS of overload operator.

Any ideas? (I really tried a lot to avoid duplicate questions)

Upvotes: 0

Views: 199

Answers (1)

Victor Padureanu
Victor Padureanu

Reputation: 614

You can do it using another type.

#include <string>
#include <iostream>

template<typename T>
class MyTypeHelper
{
public:
    T x;
    T* y;

    MyTypeHelper(T* t) : x(*t), y(t)
    {

    }
};

class MyType
{
public:
    std::string x;

    MyTypeHelper<MyType> operator<<(MyType& i)
    {
        MyTypeHelper<MyType> h(this);
        x += i.x;

        return h;
    }

    MyTypeHelper<MyType> operator<<(MyTypeHelper<MyType>& i)
    {
        MyTypeHelper<MyType> h(this);
        x += i.y->x;
        *(i.y) = i.x;

        return h;
    }
};

int main(int argc, char* argv[])
{
    {
        MyType A, B, C;
        A.x = "A";
        B.x = "B";
        C.x = "C";

        B << A;

        std::cout << A.x << " " << B.x << " " << C.x << std::endl;
    }
    {
        MyType A, B, C;
        A.x = "A";
        B.x = "B";
        C.x = "C";

        C << (B << A);

        std::cout << A.x << " " << B.x << " " << C.x << std::endl;
    }

    return 0;
}

Upvotes: 1

Related Questions