количество параметров функции
От: Hard_Club  
Дата: 26.11.09 23:09
Оценка:
Как узнать фактическое количество параметров, переданных в функцию с вариантным количеством параметров?
Re: количество параметров функции
От: remark Россия http://www.1024cores.net/
Дата: 27.11.09 04:41
Оценка: +1
Здравствуйте, Hard_Club, Вы писали:

H_C>Как узнать фактическое количество параметров, переданных в функцию с вариантным количеством параметров?


никак


1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: количество параметров функции
От: rg45 СССР  
Дата: 27.11.09 06:22
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Как узнать фактическое количество параметров, переданных в функцию с вариантным количеством параметров?


Печально, но ни количество параметров ни их типы не известны.
--
Справедливость выше закона. А человечность выше справедливости.
Re: количество параметров функции
От: Afonya1  
Дата: 27.11.09 10:22
Оценка:
man stdarg

H_C>Как узнать фактическое количество параметров, переданных в функцию с вариантным количеством параметров?
Re: количество параметров функции
От: Djafar Россия  
Дата: 27.11.09 10:25
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Как узнать фактическое количество параметров, переданных в функцию с вариантным количеством параметров?

Имеется ввиду функция main() или просто функция с произвольным кол-вом параметров? func(...) ?
И откуда узнать надо? надеюсь из самой функции? ))
Не судите строго и не кидайтесь тапками, после многих лет работы с виндоус и нескольких лет работы с .NET пришлось перейти к linux и вернуться к забытым с/с++.
Re: количество параметров функции
От: Pavel Dvorkin Россия  
Дата: 27.11.09 10:44
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Как узнать фактическое количество параметров, переданных в функцию с вариантным количеством параметров?


Если передать в качестве последнего параметра некое "недопустимое" значение (терминатор), то не так уж сложно.


int Func(char* szString, ... )
{
        int nParams = 0;
    char* szCurrent = szString;
    va_list marker;
    va_start( marker, szString ); 
    while( szCurrent ) // терминатор - NULL
    { 
           nParams++;
       szCurrent = va_arg( marker, char*);
    }
    va_end( marker ); 

        // можно теперь опять поставить в начало
        // szCurrent = szString;
    // va_start( marker, szString ); 
        
        return nParams;
}

int _tmain(int argc, _TCHAR* argv[])
{
    printf("%d\n", Func("a","b","c", NULL));
    printf("%d\n", Func("a","b","c","d",NULL));
    return 0;
}
With best regards
Pavel Dvorkin
Re[2]: количество параметров функции
От: rg45 СССР  
Дата: 27.11.09 11:28
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Если передать в качестве последнего параметра некое "недопустимое" значение (терминатор), то не так уж сложно.


А если не передать? А если передать вообще совсем не то, что ожидает функция? Получается, что рассчитывать на правильную работу функции мы можем только в том случае, если сами контролируем все ее вызовы. И то не можем, потому что мы люди и тоже иногда ошибаемся.
--
Справедливость выше закона. А человечность выше справедливости.
Re[3]: количество параметров функции
От: Pavel Dvorkin Россия  
Дата: 27.11.09 11:44
Оценка: :)
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>Если передать в качестве последнего параметра некое "недопустимое" значение (терминатор), то не так уж сложно.


R>А если не передать? А если передать вообще совсем не то, что ожидает функция?


Если функции передать не то, что она ожидает, то хорошего будет мало.

>Получается, что рассчитывать на правильную работу функции мы можем только в том случае, если сами контролируем все ее вызовы. И то не можем, потому что мы люди и тоже иногда ошибаемся.


Совершенно верно. Но на безрыбье и рак рыба
With best regards
Pavel Dvorkin
Re[3]: количество параметров функции
От: Pavel Dvorkin Россия  
Дата: 30.11.09 09:37
Оценка:
Здравствуйте, rg45, Вы писали:


PD>>Если передать в качестве последнего параметра некое "недопустимое" значение (терминатор), то не так уж сложно.


R>А если не передать? А если передать вообще совсем не то, что ожидает функция? Получается, что рассчитывать на правильную работу функции мы можем только в том случае, если сами контролируем все ее вызовы. И то не можем, потому что мы люди и тоже иногда ошибаемся.


Кстати, один вопрос к тебе. А как ты вообще собираешься получить параметры внутри функции с переменным их числом, если, конечно, явно не передавать их число как еще один параметр ?
With best regards
Pavel Dvorkin
Re: количество параметров функции
От: Sni4ok  
Дата: 30.11.09 11:04
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Как узнать фактическое количество параметров, переданных в функцию с вариантным количеством параметров?


нагенерите макросами шаблонные функции хелперы, которые будут знать колл. параметров у себя, и будут это калличество передавать в функцию с неопределённым колл. параметров- либо с помощью параметра шаблона, либо как первый параметр функции, тоесть:

//есть у вас функция с переменным числом параметров, которая колл. параметров принимает первым аргументом
void my_func_impl(int n_args, ...);

#define DECL_HEADER(z, n, text) BOOST_PP_COMMA_IF(n) typename BOOST_PP_CAT(T, n)
#define DECL_DECLARATION(z, n, text) BOOST_PP_COMMA_IF(n) const BOOST_PP_CAT(T, n)& BOOST_PP_CAT(t, n)
#define DECL_VALUE(z, n, text) BOOST_PP_COMMA_IF(n) BOOST_PP_CAT(t, n)
#define MY_FUNC(z, n, text) \
template< BOOST_PP_REPEAT(n, DECL_HEADER, ) > \
void my_func( BOOST_PP_REPEAT(n, DECL_DECLARATION, ) ){ \
    return my_func_impl(n, BOOST_PP_REPEAT(n, DECL_VALUE, ) ); \
}
BOOST_PP_REPEAT_FROM_TO(1, 10, MY_FUNC, )

//ну а вызываете потом просто функцию хелпер my_func
Re[4]: количество параметров функции
От: rg45 СССР  
Дата: 30.11.09 18:36
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Кстати, один вопрос к тебе. А как ты вообще собираешься получить параметры внутри функции с переменным их числом, если, конечно, явно не передавать их число как еще один параметр ?


Понятное дело, что если используются функции с переменным числом параметров, то каким-то образом прийдется передавать в функцию информацию о количестве параметров. Но основная мысль моего предыдущего поста, в чем я пытался вас убедить — что имеет смысл вообще отказаться от использования функций с переменным числом параметров, как от средств, в корне подрывающих надежность программ. По крайней мере, при программировании на C++.
--
Справедливость выше закона. А человечность выше справедливости.
Re[2]: количество параметров функции
От: Кодт Россия  
Дата: 30.11.09 22:08
Оценка:
Здравствуйте, Sni4ok, Вы писали:

S>нагенерите макросами шаблонные функции хелперы, которые будут знать колл. параметров у себя, и будут это калличество передавать в функцию с неопределённым колл. параметров- либо с помощью параметра шаблона, либо как первый параметр функции, тоесть:


А можно сделать без тыщи сигнатур. На списках, которые строятся инфиксным оператором.
Пример — boost::format("hello %1% world %2%") % "alfa" % beta.

При известной ловкости рук, велосипед строится за считанные минуты!

Если нужна информация о типах во время компиляции, то результат boost::tuple<...> % T = tuple<...,T>.
Соответственно, шаблон функции, принимающей такой кортеж, знает про аргументы всё на свете.

Если информация о типах нужна только во время исполнения — то vector<boost::any> % T = vector<any>.
Может быть, не any, а variant (вряд ли функция настолько всеядна).
Скажем, для форматированного вывода есть смысл собирать variant<char,int,double,string> — и, насколько это возможно, приводить тип аргумента к одному из известных. (И посылать к чертям, если тип не приводится, ибо).

Разумеется, можно и нужно дошлифовать сбор и передачу параметров, чтобы избежать копирований.
Поскольку все значения выражения (x() % y % z % t) живут до конца полного выражения, можно собирать коллекции указателей/ссылок.
поправил ссылку на буст-формат
Перекуём баги на фичи!
Re[5]: количество параметров функции
От: Pavel Dvorkin Россия  
Дата: 02.12.09 07:11
Оценка:
Здравствуйте, rg45, Вы писали:


R>Понятное дело, что если используются функции с переменным числом параметров, то каким-то образом прийдется передавать в функцию информацию о количестве параметров. Но основная мысль моего предыдущего поста, в чем я пытался вас убедить — что имеет смысл вообще отказаться от использования функций с переменным числом параметров, как от средств, в корне подрывающих надежность программ. По крайней мере, при программировании на C++.


Допустим. Тогда такой вопрос. Мне довелось писать примерно вот такое

void Logprintf(const char* szFormat, ...)

Смысл — вывод в лог чего-то там по формату. Форматы самые разные, написать перегруженные функции едва ли возможно. Чем заменить ?
With best regards
Pavel Dvorkin
Re[6]: количество параметров функции
От: joe_kidd  
Дата: 02.12.09 10:55
Оценка:
PD>Допустим. Тогда такой вопрос. Мне довелось писать примерно вот такое
PD>void Logprintf(const char* szFormat, ...)
PD>Смысл — вывод в лог чего-то там по формату. Форматы самые разные, написать перегруженные функции едва ли возможно. Чем заменить ?

Вывод в поток или boost::format не подойдет?
Re[7]: количество параметров функции
От: Pavel Dvorkin Россия  
Дата: 02.12.09 11:08
Оценка:
Здравствуйте, joe_kidd, Вы писали:

_>Вывод в поток


Оно-то годится, но только надо пользователю дать одну функцию, с помощью которой он мог бы все вывести.

>или boost::format не подойдет?


Из пушек по воробьям. Прикрутить boost ради такой мелочи...
With best regards
Pavel Dvorkin
Re[8]: количество параметров функции
От: andrey.desman  
Дата: 02.12.09 12:12
Оценка: :)
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Оно-то годится, но только надо пользователю дать одну функцию, с помощью которой он мог бы все вывести.


Спагетти любишь? Я вот обожаю!

typedef enum
{
    TYPE_INTEGER,
    TYPE_STRING
} TYPEID;

struct RawVar
{
    union
    {
        int integer;
        const char *string;
    } value;

    TYPEID type;
};

struct Var
{
    RawVar var;

    Var(int i)           { var.value.integer = i; var.type = TYPE_INTEGER; }
    Var(const char *str) { var.value.string = str; var.type = TYPE_STRING; }
};

void log(const char* format, int count, ...) {}

void Log(const char *f, Var a1)
{ log(f, 1, a1.var); }

void Log(const char *f, Var a1, Var a2)
{ log(f, 2, a1.var, a2.var); }

void Log(const char *f, Var a1, Var a2, Var a3)
{ log(f, 3, a1.var, a2.var, a3.var); }

void Log(const char *f, Var a1, Var a2, Var a3, Var a4)
{ log(f, 4, a1.var, a2.var, a3.var, a4.var); }

void Log(const char *f, Var a1, Var a2, Var a3, Var a4, Var a5)
{ log(f, 5, a1.var, a2.var, a3.var, a4.var, a5.var); }

void Log(const char *f, Var a1, Var a2, Var a3, Var a4, Var a5, Var a6)
{ log(f, 6, a1.var, a2.var, a3.var, a4.var, a5.var, a6.var); }

void Log(const char *f, Var a1, Var a2, Var a3, Var a4, Var a5, Var a6, Var a7)
{ log(f, 7, a1.var, a2.var, a3.var, a4.var, a5.var, a6.var, a7.var); }

void Log(const char *f, Var a1, Var a2, Var a3, Var a4, Var a5, Var a6, Var a7, Var a8)
{ log(f, 8, a1.var, a2.var, a3.var, a4.var, a5.var, a6.var, a7.var, a8.var); }

void Log(const char *f, Var a1, Var a2, Var a3, Var a4, Var a5, Var a6, Var a7, Var a8, Var a9)
{ log(f, 9, a1.var, a2.var, a3.var, a4.var, a5.var, a6.var, a7.var, a8.var, a9.var); }

void Log(const char *f, Var a1, Var a2, Var a3, Var a4, Var a5, Var a6, Var a7, Var a8, Var a9, Var a10)
{ log(f, 10, a1.var, a2.var, a3.var, a4.var, a5.var, a6.var, a7.var, a8.var, a9.var, a10.var); }

int main(void)
{
    Log("%s %d", "test", 10);
    Log("%s %d", "test", 10, "asd", 101);
    return 0;
}
Re[9]: количество параметров функции
От: andrey.desman  
Дата: 02.12.09 12:29
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>Спагетти любишь? Я вот обожаю!

Хотя строку формата наверное лучше переделать. Если информация о типе есть в аргументе, то нет смысла ее указывать еще и в строке формата. Наверное что-нибудь вроде .NET формата:
Log("args = {0}, {1}, {2}", 10, "test", "test");
Re[9]: количество параметров функции
От: Pavel Dvorkin Россия  
Дата: 02.12.09 12:34
Оценка:
Здравствуйте, andrey.desman, Вы писали:


AD>void log(const char* format, int count, ...) {}


А это не есть функция с переменным числом параметров ? Что с того, что ты ее "внутри" скрыл! И зачем ей нужно количество аргументов, что с ним делать-то ? Я формат парсить вручную не намерен, у меня vsprintf есть
With best regards
Pavel Dvorkin
Re[10]: количество параметров функции
От: andrey.desman  
Дата: 02.12.09 12:43
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

AD>>void log(const char* format, int count, ...) {}

PD>А это не есть функция с переменным числом параметров ? Что с того, что ты ее "внутри" скрыл! И зачем ей нужно количество аргументов, что с ним делать-то ? Я формат парсить вручную не намерен, у меня vsprintf есть

Ну дык в топике как раз обсуждаются всякие бяки с переменным количеством аргументов. И что количество аргументов не узнать, и что передано может быть меньше, или передано одно, а в формате сказано другое...
Да, я скрыл ее внутри, но ее имплементация имеет всю нужную инфу. vsprintf использовать конечно не получится.
Re[6]: количество параметров функции
От: rg45 СССР  
Дата: 02.12.09 12:49
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, rg45, Вы писали:



R>>Понятное дело, что если используются функции с переменным числом параметров, то каким-то образом прийдется передавать в функцию информацию о количестве параметров. Но основная мысль моего предыдущего поста, в чем я пытался вас убедить — что имеет смысл вообще отказаться от использования функций с переменным числом параметров, как от средств, в корне подрывающих надежность программ. По крайней мере, при программировании на C++.


PD>Допустим. Тогда такой вопрос. Мне довелось писать примерно вот такое


PD>void Logprintf(const char* szFormat, ...)


PD>Смысл — вывод в лог чего-то там по формату. Форматы самые разные, написать перегруженные функции едва ли возможно. Чем заменить ?


Ну тут сам доктор прописал реализовать как вывод в поток:
my_log << Warning << __FUNCTION__ << "Connection string of unexpected format: '" << ConnectionString << "'" << std::flush;


А сам класс лога при этом еще может добавлять дату/время и выполнять некоторое форматирование. В результате в лог-файле строки будут иметь примерно такой вид:
[10.09.2009 0:32:20][Warning][my_server::OracleConnectionProvider::connect] : Connection string of unexpected format: 'ПРЕВЕД!'
--
Справедливость выше закона. А человечность выше справедливости.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.