Здравствуйте, quantez, Вы писали:
Q>Пользоваться можно примерно так:
Q>int main()
Q>{
Q> QTSMFI manipulator = &QTextStream::putInt;
Q> QTextStream* stream = getStream(); // Взять откуда-нибудь поток.
Q> (stream->*manipulator)( 18 ); // Вызвать функцию-член объекта *stream, на которую
Q> // указывает f (т. е. QTextStream::putInt)
Q> // Или так
Q> QTextStream& ref = getStreamRef();
Q> (ref.*manipulator)( 20 );
Q>}
Скорее, вот так. (К сожалению, сам никогда библиотекой QT не пользовался — поэтому домыслы по аналогии с STL).
Манипуляторы — это функции, подмешиваемые во ввод/вывод потока:
cout << setfill('*') << setwidth(10) << 123 << endl;
// *******123
Для этого, во-первых, переопределяются операторы << и >>, а во-вторых, манипуляторы с аргументами возвращают некий функтор (объект, связывающий эти аргументы и принимающий на вход поток).
Нуль-арный манипулятор — проще всего:
// где-то есть такой оператор...
QTextStream& operator << (QTextStream& s, QTextStreamFunction f)
{
return f(s);
}
// пишем собственный манипулятор
QTextStream& http_header_endl(QTextStream& s)
{
s << "\r\r";
s.flush();
return s;
}
int main()
{
QTextStream cgi;
....
cgi << "404 Not found" << http_header_endl;
}
Унарные — как я уже сказал, требуют некий промежуточный объект. Писать классы таких объектов каждый раз — может быть лениво, поэтому воспользуемся шаблонами.
// функтор
template<class A>
struct qtsmf_binder // qts(tream)m(ember)f(unction)
{
typedef void (QTextStream::*F)(A); // указатель на функцию-член
F f_;
A a_;
qtsfm_binder(F f, A a) : f_(f), a_(a) {}
QTextStream& operator()(QTextStream& s) const // сам функтор - это уже нуль-арный манипулятор
{
(s.*f_)(a_);
return s;
}
};
// порождающая функция (чтобы не вписывать тип вручную, а выводить его)
template<class A> qtsmf_binder<A> make_manip(void (QTextStream::*f)(A), A a)
{
return qtsfm_binder<A>(f,a);
}
// оператор, принимающий наш манипулятор
template<class A>
QTextStream& operator << (QTextStream& s, qtsfm_binder<A> f)
{
return f(s);
}
// создадим манипулятор с типичным значением
static qtsmf_binder<int> yet_another_hex (&QTextStream::setIntegerBase, 16);
int main()
{
QTextStream out;
....
out << make_manip(&QTextStrean::setIntegerBase,16) << 0xDEADBEEF;
out << yet_another_hex << 0xBADC0DE;
out << hex << 0xB00B5;
}