Привет Всем!
Никто не подскажет что это значит?
typedef QTextStream & (*QTextStreamFunction)(QTextStream &);// manipulator function
typedef void (QTextStream::*QTSMFI)(int); // manipulator w/int argument
typedef void (QTextStream::*QTSMFC)(QChar); // manipulator w/QChar argument
А то я уже начинаю сомневаться в том что знаю C/C++. Никогда до этого момента с таким не сталкивался.
Это реально рабочий код. Кусок выдран из файла qtextstream.h входящего в состав библиотеки Qt 4.0.1
Жду ответа=))
Здравствуйте, gkv, Вы писали:
gkv>Привет Всем!
gkv>Никто не подскажет что это значит?
gkv>gkv>typedef QTextStream & (*QTextStreamFunction)(QTextStream &);// manipulator function
gkv>typedef void (QTextStream::*QTSMFI)(int); // manipulator w/int argument
gkv>typedef void (QTextStream::*QTSMFC)(QChar); // manipulator w/QChar argument
gkv>
gkv>А то я уже начинаю сомневаться в том что знаю C/C++. Никогда до этого момента с таким не сталкивался.
gkv>Это реально рабочий код. Кусок выдран из файла qtextstream.h входящего в состав библиотеки Qt 4.0.1
gkv>Жду ответа=))
Это указатели на функции
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
typedef QTextStream & (*QTextStreamFunction)(QTextStream &);// manipulator function
Определяет QTextStreamFunction как указатель на функцию принимающую аргумент типа ссылка на QTextStream и возвращающую ссылку на QTextStream.
typedef void (QTextStream::*QTSMFI)(int); // manipulator w/int argument
Определяет QTSMFI как указатель на член-функцию класса QTextStream принимающую аргумент типа int и возвращающую void.
typedef void (QTextStream::*QTSMFC)(QChar); // manipulator w/QChar argument
Определяет QTSMFC как указатель на член-функцию класса QTextStream принимающую аргумент типа QChar и возвращающую void.
Здравствуйте, gkv, Вы писали:
gkv>Никто не подскажет что это значит?
gkv>typedef QTextStream & (*QTextStreamFunction)(QTextStream &);// manipulator function
Указатель на функцию типа:
QTextStream& func( QTextStream& );
gkv>typedef void (QTextStream::*QTSMFI)(int); // manipulator w/int argument
gkv>typedef void (QTextStream::*QTSMFC)(QChar); // manipulator w/QChar argument
Указатели на функции-члены класса QTextStream:
class QTextStream {
public:
...
void putInt( int ); // w/int
void putChar( QChar ); // w/QChar
};
Пользоваться можно примерно так:
int main()
{
QTSMFI manipulator = &QTextStream::putInt;
QTextStream* stream = getStream(); // Взять откуда-нибудь поток.
(stream->*manipulator)( 18 ); // Вызвать функцию-член объекта *stream, на которую
// указывает f (т. е. QTextStream::putInt)
// Или так
QTextStream& ref = getStreamRef();
(ref.*manipulator)( 20 );
}
=))) Пасиб! Да, понял. Просто не работал с указателями на функции до этого. Забавно довольно.
Здравствуйте, gkv, Вы писали:
gkv>Привет Всем!
gkv>Никто не подскажет что это значит?
gkv>gkv>typedef QTextStream & (*QTextStreamFunction)(QTextStream &);// manipulator function
gkv>typedef void (QTextStream::*QTSMFI)(int); // manipulator w/int argument
gkv>typedef void (QTextStream::*QTSMFC)(QChar); // manipulator w/QChar argument
gkv>
gkv>А то я уже начинаю сомневаться в том что знаю C/C++. Никогда до этого момента с таким не сталкивался.
gkv>Это реально рабочий код. Кусок выдран из файла qtextstream.h входящего в состав библиотеки Qt 4.0.1
gkv>Жду ответа=))
Вообще, при разборе такого рода конструкций удобно применять правило "право-лево".
Посмотри тут
http://www.kalinin.ru/programming/cpp/17_07_00.shtml
Здравствуйте, 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;
}