0

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)

5
  • Can't you just overload operator <<= and avoid the ambiguity altogether? Commented Feb 2, 2018 at 22:40
  • You are absolutely right and i will do so if technically what i ask is not possible. Commented Feb 2, 2018 at 22:43
  • 1
    B << A is another way of writing operator<<(B, A) or B.operator<<(A). The operator has no knowledge about the rest of the expression, like if there are any ()'s present. Commented Feb 2, 2018 at 22:49
  • If that is really the case, you may write as an answer and i might accept it. Commented Feb 2, 2018 at 22:51
  • @BoPersson For the sake of nitpicking, there is subtle difference between B<<A and operator<<(B,A). The standard states: "If an operator function is invoked using operator notation, argument evaluation is sequenced as specified for the built-in operator" (It is not really relevant to the question.) Commented Feb 2, 2018 at 22:57

1 Answer 1

1

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;
}
Sign up to request clarification or add additional context in comments.

1 Comment

"Just add an additional level of indirection!" :) It really seems that almost all CS problems can be solved like this... as the proverb goes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.