Re[2]: wsprintf
От: Кодт Россия  
Дата: 29.03.03 13:03
Оценка: 20 (2)
Здравствуйте, JohnRus, Вы писали:

JR>А как сделать чтобы эти параметры могли быть любого типа?


Вообще-то, функция, объявленная как f(args, ...) принимает в ... параметры любого типа.
Но она должна сама знать, что есть что. Потому что на стек кладется копия значения, а у разных типов — и размеры разные.
Подробнее — см. va_list, va_start, va_arg

На 32-битных платформах маленькие целые числа (char, short) расширяются до int и кладутся на стек.
Поэтому printf("%d %d %d", '1', '2', '3') напечатает "48 49 50", а не жуткую кашу.
Но это — implementation-defined.

Кстати, double занимает 8 байт, поэтому printf("%g", (float)1.2) выведет нечто страшное вместо ожидаемого "1.2"

Компилятор GCC делает предупреждение, если передать структуру/объект.


Самый же рулезный способ передачи множества параметров на С++ — это stream-like.
Т.е. перекрыть оператор << и напихать параметры поштучно.

Рабочий пример: форматирование строки с произвольным следованием аргументов
http://www.rsdn.ru/Forum/?mid=79582
Автор: DarkGray
Дата: 01.08.02
— часть 1
http://www.rsdn.ru/Forum/?mid=81162
Автор: DarkGray
Дата: 06.08.02
— часть 2



Каркас программы может выглядеть так:
class ArgList
{
public:
  // запись
  ArgList& operator << (ArgList&, arg1_t arg);
  ArgList& operator << (ArgList&, arg2_t arg);
  ...
  // столько сигнатур, сколько нужно

public:
  // чтение, например, такое.
  int count() const;
  uniform_arg_t arg(int index) const;
};

.....

void execute(const ArgList& arglist);
// как вызывать:
execute(ArgList() << 1 << '2' << "3" << std::string("4"));

/////////////////////////////////////////////////////

// возможно, прокатит такое определение
template< class Exec >
void operator << (Exec exec, ArgList arglist) { exec(arglist); }

// тогда вообще можно написать
execute << 1 << '2' << "3" << std::string("4");
Перекуём баги на фичи!
wsprintf
От: Stream Россия  
Дата: 28.03.03 23:05
Оценка:
никогда не видел примеров как делаются функции, например,
такие как wsprintf, т.е. с динамическим числом параметров...
можно конечно передавать что-нибудь типа указателя
на какую-нибудь динамическую структуру, но так чтобы
число параметров в сигнатуре менялось ... не видел!

а, ну и вопрос то сам: как такую функцию написать?

заранее спасибо!!!
Re: wsprintf
От: IT Россия linq2db.com
Дата: 28.03.03 23:23
Оценка:
Здравствуйте, Stream, Вы писали:

S>никогда не видел примеров как делаются функции, например, такие как wsprintf, т.е. с динамическим числом параметров...


А что нужно? Форматирование?

void MyMultipleParameterFunction(const char *forumat, ...)
{
    va_list  arg;
    va_start(arg, format);

    char     buf[256]; // тут всё зависит от потребностей
    vsprintf(buf, format, arg);

    // buf содержит отформатированную строку
}
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: wsprintf
От: Stream Россия  
Дата: 29.03.03 01:11
Оценка:
Здравствуйте, IT, Вы писали:

IT>А что нужно? Форматирование?


IT>
IT>void MyMultipleParameterFunction(const char *forumat, ...)
IT>{
IT>    // ...
IT>}
IT>


Спасибо, вы уже ответили на мой вопрос ...
Re[3]: wsprintf
От: JohnRus Россия  
Дата: 29.03.03 04:47
Оценка:

2 stream:
Видишь, по всей видимости их все для форматирования и применяют.

2 all: Интересно, есть ли win32 аналог для strstream
Re: wsprintf
От: JohnRus Россия  
Дата: 29.03.03 10:43
Оценка:
А как сделать чтобы эти параметры могли быть любого типа?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.