1

I have a class, let's call it Foo, which contains the 3 following methods (overloading the left-associative < binary operator):

... operator<(A a) { return *this; }
... operator<(B b) { return *this; }
... operator<(C c) { return *this; }

A, B, C classes are not related in any way(if that, is of any matter).

Now In my program I only have the 2 following cases:

A a = new A();
B b = new B();
C c = new C();

(First Case): new Foo() < a < b;

or

(Second Case): new Foo() < a < b < c;

Whenever I have the first case (which ends with b), I want to execute a function run() when I have read(I know) the b instance. So the idea is that I would have the following code in the Foo class:

... operator<(B b)
{
    run();
}

Now when I have the code of the first case, run() is being executed.

The problem is that when I have code like in the second case(which ends in c). I want to execute the run() function again but NOT until I know what c is. So If I have the previous piece of code run() will be called when doing < b which is not what I want as I don't know c yet. If I add run() in operator<(C c) I will call run() twice.

In a few words what I want to accomplish is when having the first case call run() at operator<(B b) and when I have the second case ONLY call run at operator<(C c).

Any ideas on how this can be solved(if it can)?

insumity
  • 5,311
  • 8
  • 36
  • 64
  • 4
    Overriding operators in non standard ways is frowned upon as it is non intuitive to use for the maintainer. Prefer to use methods with a good name that explains what is happening. – Martin York Dec 20 '10 at 19:07
  • 5
    You are mixing the use of objects with pointers. The first step here is to understand the difference and then most of your problems will go away. – Martin York Dec 20 '10 at 19:08
  • 1
    I'm with @Martin on this. You're violating [the basic rules of operator overloading](http://stackoverflow.com/questions/4421706/operator-overloading/4421708#4421708). Consider using functions instead. Oh, and what you're looking for is expression templates. – sbi Dec 20 '10 at 19:39
  • (You should properly @address people in comment replies, so that your replies show up in their "Responses" tab.) No you do not _need_ to do that. I'm certain the way you want to do it will seem _much_ uglier to most seasoned C++ programmers than a solution that involves calling nicely named functions. Abusing operator overloading to make code "neater" basically _always_ fails. Hence the first two basic rules. – sbi Dec 27 '10 at 22:20

3 Answers3

2

You could create separate proxy object return types, so when you define an operator for that proxy object, you know which types have gone before it.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • 1
    This is way beyond the OP ability level. There are many more fundamental problems that need to be solved first. – Martin York Dec 20 '10 at 19:09
  • 2
    My opinion is: If OP is so unstructured and wrong using instances and pointers then he/she is in the same way unstructured and wrong in it's overall software design. – mmmmmmmm Dec 20 '10 at 19:18
0

You have to create a syntax tree before, and than evaluate it. So you are creating a DSL, domain specific language.

read this http://codeidol.com/cpp/cpp-template-metaprogramming/Domain-Specific-Embedded-Languages/-10.5.-Blitz-and-Expression-Templates/

or you can use the boost::proto

0
class PreFoo {
public:
    PreFoo() { ... }
    PreFoo & operator<<(A a) { ...; return *this; }
    PreFoo & operator<<(B b) { ...; return *this; }
    PreFoo & operator<<(C c) { ...; return *this; }

    int aa, bb, cc; // save your information
};

PreFoo MakeFoo() { return PreFoo(); }

class Foo {
public:
    Foo(const PreFoo & pre) { run(); } // implicit conversion

    void run() {} // your run!!
};


void g() {
  A a; B b; C c;
  // implicit conversion at the end
  Foo foo1 = MakeFoo() << a << b;
  Foo foo2 = PreFoo() << a << b << c;
}
Martin York
  • 257,169
  • 86
  • 333
  • 562
Alexey Malistov
  • 26,407
  • 13
  • 68
  • 88