Перегрузка оператора цепочкой - PullRequest
0 голосов
/ 30 августа 2010

Я бы хотел перегрузить оператор << для цепочки, как показано ниже </p>

function1(param1, param2)<< obj2 << obj3 << string4

function1 вернул бы объект.

Что я хочу сделать, это после string4, мне нужно вызватьфункция с использованием param1, param2.

Мои вопросы будут

  1. Как узнать, что string4 - это последние параметры в выражении, и, следовательно, мне нужно вызвать другую функцию2, используя param1 и param2, или это не так?Как это сделать?

  2. Как передать param1 и param2 в вызываемую функцию?Я не смог сохранить param1 и param2 в объекте, поскольку он является многопоточным.

Спасибо.

Ответы [ 5 ]

1 голос
/ 30 августа 2010

Как отметил Фрерих Раабе, одним из возможных решений является использование деструктора временного объекта.Тем не менее, это означает, что вам каким-то образом НУЖНО вызывать все аргументы в строке, что запрещает следующий синтаксис:

auto stream = function1(param1, param2) << param3;
stream << param4;
stream << stringG; // call here

Библиотека IO Stream в стандартной библиотеке обходит проблему, используя глобальный объект как«маркер»: std::endl.Это может быть другой вариант.

Обратите внимание, что если вы идете маркером, вы можете отменить требование не копировать.

В конце концов, это больше вопрос дизайна, чем вопросреализации, так что это ваш вызов.

class Stream
{
public:
  struct Marker {};
  static Marker End;

  Stream(type1, type2);

  void operator<<(Marker) const { function2(m1,m2); }
  Stream& operator<<(...);

private:
  type1 m1;
  type2 m2;
};

Весело провести время:)

1 голос
/ 30 августа 2010

Вы можете вернуть вспомогательный объект из function1 по значению, которое вызывает в его деструкторе function2.

Рассмотрите этот пример:

#include <iostream>

using namespace std;

void function2( int i, int j ) {
    cout << "function2 called with " << i << " and " << j << endl;
}

struct Function2Caller {
  Function2Caller( int param1, int param2 ) : m_param1( param1 ), m_param2( param2 ) {}
  ~Function2Caller() { function2( m_param1, m_param2 ); }

  int m_param1, m_param2;
};

Function2Caller &operator<<( Function2Caller &obj, int x ) {
    cout << "Streaming " << x << endl;
    return obj;
}

Function2Caller function1( int i, int j ) {
    cout << "function1 called with " << i << " and " << j << endl;
    return Function2Caller( i, j );
}

int main() {
    function1( 2, 3 ) << 4 << 6;
}

Эта программа печатает

function1 called with 2 and 3
Streaming 4
Streaming 6
function2 called with 2 and 3

Идея состоит в том, что в конце вашей строки объект Function2Caller выходит из области видимости, и деструктор затем выполняет свою работу.

Обратите внимание, что при реализации этого вы, вероятно, должны запретить копированиеобъектов Function2Caller и делают function1 единственным, кто может вызвать конструктор Function2Caller.

0 голосов
/ 30 августа 2010

Вы передаете функтор в конце, так легче

 class myfun {
 public:
         void operator()(const string& param1, const string& param2, const string& values) const {
                 std::cout << "param1: " << param1 << "param2: " << param2 << " value: " << values << std::endl;
         }
 };

 class A {
         string m_param1, m_param2;
         string values;
 public:
         A(string param1, string param2):m_param1(param1), m_param2(param2) { }

         A& operator << (const string& str) {
                 values += str;
                 return *this;
         }

         A& operator << (const myfun& myfun) {
                 myfun(m_param1, m_param2, values);
                 return *this;
         }
         };

 A fun(string param1, string param2) {
       return A(param1, param2);
 };

 int main() {
         fun("a", "b") << "xyz" << myfun();
         return 0;
 }
0 голосов
/ 30 августа 2010

Если function1 что-то возвращает (скажем, int), вы сможете отложить все вычисления до тех пор, пока не будет использовано их значение. , Вы должны вернуть объект, который может быть преобразован в int (путем реализации int operator int() в качестве функции-члена).

В реализации function1 вы ее создаете. Объект также будет реализовывать <<. В той функции-члене, которая выполняет преобразование, вы используете все значения, которые вы собрали в качестве параметров и передали с помощью оператора <<.

0 голосов
/ 30 августа 2010

Откуда я знаю, что string4 последний параметры в выражении и, следовательно, Мне нужно вызвать функцию, используя param1 и param2 или это невозможно сделать это?

function1(param1, param2)<< obj2 << obj3 << string4

не делает то, что вы думаете, что делает. Здесь function1 вычисляется первым, результирующий объект используется для вызова operator<< с obj2 в качестве аргумента и так далее ...

Если вы хотите вызвать function1 в конце, это должно произойти после того, как вы вызвали operator<< с string4 в качестве аргумента.

Как передать param1 и param2 в функция должна быть вызвана? Я не мог сохранить param1 и param2 в объект как он многопоточный.

Ваш op<< должен вернуть объект типа T, для которого определено op(), чтобы вы могли все это сделать с param1 и param2 в самом конце.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...