Выполнить определенный код при перегрузке операторов C ++ - PullRequest
1 голос
/ 20 декабря 2010

У меня есть класс, назовем его Foo , который содержит 3 следующих метода (перегрузка левоассоциативного <двоичного оператора): </p>

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

Классы A, B, C никоим образом не связаны (если это имеет какое-либо значение).

Теперь В моей программе у меня есть только 2 следующих случая:

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

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

или

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

Всякий раз, когда у меня есть первый случай (который заканчивается b), я хочу выполнить функцию run (), когда прочитал (я знаю) экземпляр b. Итак, идея в том, что у меня будет следующий код в классе Foo :

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

Теперь, когда у меня есть код первого случая, run() выполняется.

Проблема в том, что когда у меня есть код, как во втором случае (который заканчивается c). Я хочу снова выполнить функцию run(), но НЕ, пока не узнаю, что такое c. Так что, если у меня есть предыдущий кусок кода, run() будет вызываться при выполнении < b это не то, чего я хочу, поскольку я пока не знаю c. Если я добавлю run() в operator<(C c), я позвоню run() дважды.

В нескольких словах я хочу, чтобы при первом вызове дела run() в operator<(B b) и при втором вызове ТОЛЬКО в деле operator<(C c).

Есть идеи, как это можно решить (если можно)?

Ответы [ 3 ]

2 голосов
/ 20 декабря 2010

Вы можете создать отдельные типы возвращаемых прокси-объектов, поэтому, когда вы определяете оператор для этого прокси-объекта, вы знаете, какие типы были перед ним.

0 голосов
/ 20 декабря 2010
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;
}
0 голосов
/ 20 декабря 2010

Вы должны создать синтаксическое дерево раньше, а затем оценить его. Итак, вы создаете DSL, специфичный для домена язык.

прочитайте это http://codeidol.com/cpp/cpp-template-metaprogramming/Domain-Specific-Embedded-Languages/-10.5.-Blitz-and-Expression-Templates/

или вы можете использовать boost :: proto

...