Преимущества/изменения Встроенной Платформы Поблочного тестирования VS2008
Вероятно, вы не должны этого делать, и вы, вероятно, сможете делать то, что хотите, более безопасным и простым способом. Технически, чтобы использовать переменное количество аргументов в C, вы включаете stdarg.h. Отсюда вы получите тип va_list
, а также три функции, которые работают с ним, называемые va_start ()
, va_arg ()
и va_end ( )
.
#include<stdarg.h>
int maxof(int n_args, ...)
{
va_list ap;
va_start(ap, n_args);
int max = va_arg(ap, int);
for(int i = 2; i <= n_args; i++) {
int a = va_arg(ap, int);
if(a > max) max = a;
}
va_end(ap);
return max;
}
Если вы спросите меня, это беспорядок. Это выглядит плохо, небезопасно и полно технических деталей, которые не имеют ничего общего с тем, чего вы концептуально пытаетесь достичь. Вместо этого рассмотрите возможность использования перегрузки или наследования / полиморфизма, шаблона построения (как в operator << ()
в потоках) или аргументов по умолчанию и т.д. Все это безопаснее: компилятор узнает больше о том, что вы '
Если вы знаете диапазон числа аргументов, которые будут предоставлены, вы всегда можете использовать перегрузку некоторых функций, например
f(int a)
{int res=a; return res;}
f(int a, int b)
{int res=a+b; return res;}
и так далее ...
Как уже говорили другие, varargs в стиле C. Но вы также можете сделать нечто подобное с аргументами по умолчанию.
Возможно, вам потребуется перегрузка или параметры по умолчанию - определите ту же функцию с параметрами по умолчанию:
void doStuff( int a, double termstator = 1.0, bool useFlag = true )
{
// stuff
}
void doStuff( double std_termstator )
{
// assume the user always wants '1' for the a param
return doStuff( 1, std_termstator );
}
Это позволит вам вызвать метод одним из четырех различных вызовов:
doStuff( 1 );
doStuff( 2, 2.5 );
doStuff( 1, 1.0, false );
doStuff( 6.72 );
.. .или вы можете искать соглашения о вызовах v_args от C.
Не существует стандартного способа C ++ сделать это, не прибегая к varargs в стиле C ( ...
).
Конечно, есть аргументы по умолчанию, которые вроде "выглядят" как номер переменной аргументов в зависимости от контекста:
void myfunc( int i = 0, int j = 1, int k = 2 );
// other code...
myfunc();
myfunc( 2 );
myfunc( 2, 1 );
myfunc( 2, 1, 0 );
Все четыре вызова функций вызывают myfunc
с различным количеством аргументов. Если ничего не указано, используются аргументы по умолчанию. Однако учтите, что вы можете опустить только завершающие аргументы. Выхода нет,
Помимо varargs или перегрузки, вы можете рассмотреть возможность объединения ваших аргументов в std :: vector или других контейнерах (например, std :: map). Примерно так:
template <typename T> void f(std::vector<T> const&);
std::vector<int> my_args;
my_args.push_back(1);
my_args.push_back(2);
f(my_args);
Таким образом вы получите безопасность типов, и логический смысл этих вариативных аргументов станет очевидным.
Конечно, этот подход может иметь проблемы с производительностью, но вы не должны беспокоиться о них, если не уверены, что вы не может заплатить цену. Это своего рода "питонический" подход к C ++ ...
Вариативные функции в стиле C поддерживаются в C ++.
Однако большинство библиотек C ++ используют альтернативную идиому, например, тогда как функция 'c' printf
принимает переменные аргументы, Объект c ++ cout
использует перегрузку <<
, которая обращается к безопасности типов и ADT (возможно, за счет простоты реализации).
В C ++ 11 есть способ создавать шаблоны переменных аргументов, которые приводят к действительно элегантному и безопасному для типов способу иметь функции с переменными аргументами. Сам Бьярн приводит хороший пример printf с использованием шаблонов переменных аргументов в C ++ 11FAQ .
Лично я считаю это настолько элегантным, что я даже не стал бы возиться с функция переменного аргумента в C ++ до тех пор, пока этот компилятор не будет поддерживать шаблоны переменных аргументов C ++ 11.
Единственный способ - использовать аргументы переменных стиля C, как описано здесь . Обратите внимание, что это не рекомендуется, так как это не типизировано и не подвержено ошибкам.