Необычные typedef
От: gkv  
Дата: 28.10.05 17:59
Оценка:
Привет Всем!
Никто не подскажет что это значит?

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

Жду ответа=))
Re: Необычные typedef
От: gid_vvp  
Дата: 28.10.05 18:05
Оценка:
Здравствуйте, 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>>
Re: Необычные typedef
От: igna Россия  
Дата: 28.10.05 18:08
Оценка: +1
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.
Re: Необычные typedef
От: quantez  
Дата: 28.10.05 18:20
Оценка:
Здравствуйте, 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 );
}
Re: Необычные typedef
От: gkv  
Дата: 28.10.05 18:32
Оценка:
=))) Пасиб! Да, понял. Просто не работал с указателями на функции до этого. Забавно довольно.
Re: Необычные typedef
От: Андрей Коростелев Голландия http://www.korostelev.net/
Дата: 28.10.05 20:55
Оценка:
Здравствуйте, 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
-- Андрей
Re[2]: Необычные typedef
От: Кодт Россия  
Дата: 29.10.05 09:06
Оценка: 1 (1)
Здравствуйте, 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;
}
Перекуём баги на фичи!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.