В C ++, как вы программно обнаруживаете конец последовательности формы:
object << argument1 << argument2 << argument3;
Допустим, у меня перегружен оператор<< как это
Object& operator<<(Object& object, Argument& argument) {
...
}
Вышеупомянутое выражение будет оцениваться так:
(((object << argument1) << argument2) << argument3);
Ради аргумента, скажем, объект является логгером. Я передаю данные в логгер. После того, как последний аргумент (в этом случае аргумент 3, но количество аргументов не фиксировано, конечно) передан в объект, я хочу, чтобы объект собрал сообщение и опубликовал его. Как я могу сделать это без необходимости писать что-то вроде этого:
object << argument1 << argument2 << argument3 << EOM;
Спасибо. Любой вход приветствуется.
Как отмечают другие ответы, использование маркера «конец сообщения» — хороший дизайн.
Но если вам действительно нужно то, что вы просили, вы можете сделать это следующим образом: вы реализуете идею 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
без копируемого.Вы не можете (если object
уничтожается после каждой строки). Это довольно часто, чтобы иметь что-то вроде EOM
,
Подумайте, почему возможна запись последовательности. Это случилось, потому что operator<<
возвращает ссылку на поток. Ты можешь написать:
ostream& s = object << argument1;
s << argument2
s << argument3
...
А где настоящий конец последовательности? Только вы знаете, потому что вы разрабатываете и кодируете это. Так EOM
Это хорошая обычная практика — используйте ее.