Здравствуйте, Hard_Club, Вы писали:
H_C>Как узнать фактическое количество параметров, переданных в функцию с вариантным количеством параметров?
Имеется ввиду функция main() или просто функция с произвольным кол-вом параметров? func(...) ?
И откуда узнать надо? надеюсь из самой функции? ))
Не судите строго и не кидайтесь тапками, после многих лет работы с виндоус и нескольких лет работы с .NET пришлось перейти к linux и вернуться к забытым с/с++.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Если передать в качестве последнего параметра некое "недопустимое" значение (терминатор), то не так уж сложно.
А если не передать? А если передать вообще совсем не то, что ожидает функция? Получается, что рассчитывать на правильную работу функции мы можем только в том случае, если сами контролируем все ее вызовы. И то не можем, потому что мы люди и тоже иногда ошибаемся.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, Pavel Dvorkin, Вы писали:
PD>>Если передать в качестве последнего параметра некое "недопустимое" значение (терминатор), то не так уж сложно.
R>А если не передать? А если передать вообще совсем не то, что ожидает функция?
Если функции передать не то, что она ожидает, то хорошего будет мало.
>Получается, что рассчитывать на правильную работу функции мы можем только в том случае, если сами контролируем все ее вызовы. И то не можем, потому что мы люди и тоже иногда ошибаемся.
PD>>Если передать в качестве последнего параметра некое "недопустимое" значение (терминатор), то не так уж сложно.
R>А если не передать? А если передать вообще совсем не то, что ожидает функция? Получается, что рассчитывать на правильную работу функции мы можем только в том случае, если сами контролируем все ее вызовы. И то не можем, потому что мы люди и тоже иногда ошибаемся.
Кстати, один вопрос к тебе. А как ты вообще собираешься получить параметры внутри функции с переменным их числом, если, конечно, явно не передавать их число как еще один параметр ?
Здравствуйте, 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
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Кстати, один вопрос к тебе. А как ты вообще собираешься получить параметры внутри функции с переменным их числом, если, конечно, явно не передавать их число как еще один параметр ?
Понятное дело, что если используются функции с переменным числом параметров, то каким-то образом прийдется передавать в функцию информацию о количестве параметров. Но основная мысль моего предыдущего поста, в чем я пытался вас убедить — что имеет смысл вообще отказаться от использования функций с переменным числом параметров, как от средств, в корне подрывающих надежность программ. По крайней мере, при программировании на C++.
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, 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) живут до конца полного выражения, можно собирать коллекции указателей/ссылок.
R>Понятное дело, что если используются функции с переменным числом параметров, то каким-то образом прийдется передавать в функцию информацию о количестве параметров. Но основная мысль моего предыдущего поста, в чем я пытался вас убедить — что имеет смысл вообще отказаться от использования функций с переменным числом параметров, как от средств, в корне подрывающих надежность программ. По крайней мере, при программировании на C++.
Допустим. Тогда такой вопрос. Мне довелось писать примерно вот такое
void Logprintf(const char* szFormat, ...)
Смысл — вывод в лог чего-то там по формату. Форматы самые разные, написать перегруженные функции едва ли возможно. Чем заменить ?
PD>Допустим. Тогда такой вопрос. Мне довелось писать примерно вот такое PD>void Logprintf(const char* szFormat, ...) PD>Смысл — вывод в лог чего-то там по формату. Форматы самые разные, написать перегруженные функции едва ли возможно. Чем заменить ?
Здравствуйте, andrey.desman, Вы писали:
AD>Спагетти любишь? Я вот обожаю!
Хотя строку формата наверное лучше переделать. Если информация о типе есть в аргументе, то нет смысла ее указывать еще и в строке формата. Наверное что-нибудь вроде .NET формата:
AD>void log(const char* format, int count, ...) {}
А это не есть функция с переменным числом параметров ? Что с того, что ты ее "внутри" скрыл! И зачем ей нужно количество аргументов, что с ним делать-то ? Я формат парсить вручную не намерен, у меня vsprintf есть
Здравствуйте, Pavel Dvorkin, Вы писали:
AD>>void log(const char* format, int count, ...) {} PD>А это не есть функция с переменным числом параметров ? Что с того, что ты ее "внутри" скрыл! И зачем ей нужно количество аргументов, что с ним делать-то ? Я формат парсить вручную не намерен, у меня vsprintf есть
Ну дык в топике как раз обсуждаются всякие бяки с переменным количеством аргументов. И что количество аргументов не узнать, и что передано может быть меньше, или передано одно, а в формате сказано другое...
Да, я скрыл ее внутри, но ее имплементация имеет всю нужную инфу. vsprintf использовать конечно не получится.
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, rg45, Вы писали:
R>>Понятное дело, что если используются функции с переменным числом параметров, то каким-то образом прийдется передавать в функцию информацию о количестве параметров. Но основная мысль моего предыдущего поста, в чем я пытался вас убедить — что имеет смысл вообще отказаться от использования функций с переменным числом параметров, как от средств, в корне подрывающих надежность программ. По крайней мере, при программировании на C++.
PD>Допустим. Тогда такой вопрос. Мне довелось писать примерно вот такое
PD>void Logprintf(const char* szFormat, ...)
PD>Смысл — вывод в лог чего-то там по формату. Форматы самые разные, написать перегруженные функции едва ли возможно. Чем заменить ?
Ну тут сам доктор прописал реализовать как вывод в поток:
А сам класс лога при этом еще может добавлять дату/время и выполнять некоторое форматирование. В результате в лог-файле строки будут иметь примерно такой вид:
[10.09.2009 0:32:20][Warning][my_server::OracleConnectionProvider::connect] : Connection string of unexpected format: 'ПРЕВЕД!'
--
Справедливость выше закона. А человечность выше справедливости.