определить конец оператора & lt; & lt; последовательность

В C ++, как вы программно обнаруживаете конец последовательности формы:

object << argument1 << argument2 << argument3;

Допустим, у меня перегружен оператор<< как это

Object& operator<<(Object& object, Argument& argument) {
...
}

Вышеупомянутое выражение будет оцениваться так:

(((object << argument1) << argument2) << argument3);

Ради аргумента, скажем, объект является логгером. Я передаю данные в логгер. После того, как последний аргумент (в этом случае аргумент 3, но количество аргументов не фиксировано, конечно) передан в объект, я хочу, чтобы объект собрал сообщение и опубликовал его. Как я могу сделать это без необходимости писать что-то вроде этого:

object << argument1 << argument2 << argument3 << EOM;

Спасибо. Любой вход приветствуется.

1

Решение

Как отмечают другие ответы, использование маркера «конец сообщения» — хороший дизайн.

Но если вам действительно нужно то, что вы просили, вы можете сделать это следующим образом: вы реализуете идею EOM, как обычно, а затем добавляете этот класс:

class AutoEnd
{
private:
mutable Object & m_obj;

public:
explicit AutoEnd (Object & obj) : m_obj (obj) {}
~AutoEnd () {m_obj << EOM;}

Object & obj () const {return m_obj;}
};

template <typename T>
AutoEnd const & operator << (AutoEnd const & ae, T && arg)
{
ae.obj() << std::forward<T>(arg);
return ae;
}

И вы можете использовать это так:

Object object;
...
AutoEnd(object) << argument1 << argument2 << argument3;

который будет делать то, что вы хотите. Некоторые заметки:

  • Очевидно, вы все еще можете использовать явное EOM метод после добавления AutoEnd, Это дает вам большую гибкость в использовании любого метода, который имеет смысл.
  • Ключ в этой технике — деструктор для AutoEnd, который будет вызван в конце строки, в которой он был создан.
  • Вы можете реализовать это лучше, чем выше. Самое главное, это хорошая идея, чтобы сделать конструктор AutoEnd быть приватным или как-то сигнализировать пользователю, что он не должен создавать нормальные экземпляры AutoEndпотому что они бесполезны и хранят ссылки на вас Objectи может попытаться использовать их после того, как они будут уничтожены.
  • Вы можете безопасно использовать эту технику, только если operator << за Object не выдает исключение, потому что он вызывается внутри деструктора и деструкторы не должны бросать.
  • поскольку AutoEnd предназначен для использования в качестве временного объекта, и вы можете работать только с const & из временных объектов легко, operator << получает и возвращает постоянную ссылку, а сохраненный Object ссылка объявлена ​​как mutable, На мой взгляд, это неплохой дизайн, так как AutoEnd объекты не имеют внутреннего состояния (кроме Object &) и правильность звонка operator << в этом нужно быть уверенным в другом месте (т.е. AutoEnd не нужно заботиться об этом.)
  • Вы должны сделать AutoEnd без копируемого.
3

Другие решения

Вы не можете (если object уничтожается после каждой строки). Это довольно часто, чтобы иметь что-то вроде EOM,

0

Подумайте, почему возможна запись последовательности. Это случилось, потому что operator<< возвращает ссылку на поток. Ты можешь написать:

ostream& s = object << argument1;
s << argument2
s << argument3
...

А где настоящий конец последовательности? Только вы знаете, потому что вы разрабатываете и кодируете это. Так EOM Это хорошая обычная практика — используйте ее.

0
По вопросам рекламы [email protected]