Мне нужно реализовать манипулятор iostream C ++. Читая здесь и там, кажется, что люди используют 2 способа
с помощью ios_base::xalloc
а также ios_base::iword
реализация производного класса от iostream, как пример ниже.
Мне нравится второй способ, но, вероятно, у него есть недостатки, которые я не вижу или не понимаю по сравнению с первым способом.
// Example of point 2
struct mystream : public iostream
{
ostream& o_;
mystream(ostream& o) : o_(o) {}
ostream& operator << (int a) {
// do something with o and a
o << "<A>" << a << "</A>";
return *this;
}
};
ostream mymanipulator(ostream& out) {
return mystream(out);
}
Я нашел очень хорошую реализацию пути № 2 в этом посте Кастомный манипулятор для C ++ iostream.
Мне кажется, что xalloc and iword
больше используются для хранения некоторого пользовательского внутреннего состояния для моего пользовательского потока, который будет использоваться в какой-то момент.
Я бы не рекомендовал ни одну из этих вещей.
С помощью
ios_base::xalloc
а такжеios_base::iword
Вы точно не сказали нам, как будете использовать данные, хранящиеся в потоке, но это немного не понятно iword()
каждый раз, когда вы хотите написать.
Реализация производного класса от
iostream
…
Обычно вы не хотите наследовать от потоков базовых классов. Единственный случай, когда это может быть полезно, — это когда вы оборачиваете пользовательский поток в буфер потока, но это обычно для удобства.
Другая проблема заключается в том, что ваш вставщик возвращает std::ostream
Это означает, что при объединении операторов вы будете писать только в std::ostream
базовый объект на второй записи:
mystream str;
str << 100 // writes "<A>100</A>"<< 200; // only writes 200
Идиоматическое решение состоит в том, чтобы настроить std::num_put<char>
фасет для локали вашего потока. Таким образом, вы оборачиваете функциональность непосредственно под капот потока, чтобы он не изменил способ, которым пользователь использует поток.