Использование переменных функций - PullRequest
0 голосов
/ 15 сентября 2011

Каковы преимущества использования функций с переменными значениями

void fun(int i, ...);

вместо передачи указателя на массив?

void fun(int i*);

Когда предпочтительны функции с переменными числами?

Ответы [ 4 ]

6 голосов
/ 15 сентября 2011

Сначала вы должны явно создать массив.Кроме того, было бы проблематично, если вы хотите указать параметры разных типов .

Функции Variadic не требуют создания какого-либо массива и могут работать с разными типами.

В качестве примера, я не мог бы использовать printf -функции, если мне всегда приходилось сначала создавать какой-либо массив.

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

2 голосов
/ 15 сентября 2011

Я бы посоветовал вам просто не использовать функции вариации.Однако они могут быть полезны.Например, в методах метапрограммирования шаблонов для реализации запросов во время компиляции.

  1. Поскольку компилятор не может проверить, что данный вызов функции с переменным числом аргументов передает соответствующее количество аргументов или что эти аргументы имеют соответствующие типы,Следовательно, вызов во время выполнения функции с переменными аргументами, которая передает неуместные аргументы, приводит к неопределенному поведению.
  2. В средах с чистым C альтернативные функции не имеют альтернативы, но в C ++ вы можете найти объектно-ориентированные альтернативы (также одна проблема).1008 *
  3. Функции Variadic не являются тривиальными для реализации.Если не инициализировать ap, вызов va_arg() один раз для многих или пропуск вызова va_end(ap) может привести к сбою вашей программы.

Пример близкого к неопределенному поведению:

Моя работа заключалась в том, чтобы создать объектно-ориентированную оболочку вокруг sqlite C api.Я здесь: я создал необычный интерфейс для выполнения sqlite запросов, это было что-то вроде этого:

void Query(const std::string& Query, void* Arguments, ...);

Это с одной стороны удивительно и причудливо, но: вы сразу же сталкиваетесь с неопределенным поведением, если ваши типы параметров неверны.Например:

db->Query("select * from northwind where id = ?", "Peter"); // espects int as type

приведет к неопределенному поведению.

2 голосов
/ 15 сентября 2011

Кроме того, вы не хотите передавать массив в функции с переменным числом, так как вы также хотите передать его размер. например:

myfunction(int *pArray, int NumElements)

Суть в том, что функции с переменными числами позволяют передавать много разных типов.

2 голосов
/ 15 сентября 2011

Указатель на массив предполагает предопределенный тип параметра (или структуру, если есть несколько разных типов).

Функции Variadic используются, когда вы не знаете заранее, каким будет тип параметра, и вы используете подсказку предопределенных параметров, чтобы получить эти знания (например, строку формата для printf).

...