Переменное количество параметров в функции в C++

Я бы сказал, что это должно быть

namespace :db do
  namespace :test do
    task :prepare => :environment do
      Rake::Task["db:seed"].invoke
    end
  end
end

Поскольку db: test: load не выполняется, если у вас есть config.active_record.schema_format =: sql (db: test: clone_structure is)

31
задан Carl Norum 16 October 2009 в 18:50
поделиться

4 ответа

Они называются функциями с переменными числами . Википедия перечисляет пример кода для C ++ .

Для переносимой реализации вариативного функции в программировании на C язык, стандартный заголовок stdarg.h файл следует использовать. Старший Заголовок varargs.h устарел в пользу stdarg.h. В C ++ следует использовать файл заголовка cstdarg .

Чтобы создать вариативную функцию, многоточие ( ... ) необходимо поместить в конец списка параметров. Внутри тело функции, переменная type va_list должен быть определен. Тогда макросы va_start (va_list, последнее исправление param) , va_arg (va_list, тип приведения) , va_end (va_list) можно использовать. За пример:

#include <stdarg.h>

double average(int count, ...)
{
    va_list ap;
    int j;
    double tot = 0;
    va_start(ap, count); //Requires the last fixed parameter (to get the address)
    for(j=0; j<count; j++)
        tot+=va_arg(ap, double); //Requires the type to cast to. Increments ap to the next argument.
    va_end(ap);
    return tot/count;
}
44
ответ дан 27 November 2019 в 21:49
поделиться

Aside from the other answers, if you're just trying to pass an array of integers, why not:

void func(const std::vector<int>& p)
{
    // ...
}

std::vector<int> params;
params.push_back(1);
params.push_back(2);
params.push_back(3);

func(params);

You can't call it in parameter, form, though. You'd have to use any of the variadic function listed in your answers. C++0x will allow variadic templates, which will make it type-safe, but for now it's basically memory and casting.

You could emulate some sort of variadic parameter->vector thing:

// would also want to allow specifying the allocator, for completeness
template <typename T> 
std::vector<T> gen_vec(void)
{
    std::vector<T> result(0);
    return result;
}

template <typename T> 
std::vector<T> gen_vec(T a1)
{
    std::vector<T> result(1);

    result.push_back(a1);

    return result;
}

template <typename T> 
std::vector<T> gen_vec(T a1, T a2)
{
    std::vector<T> result(1);

    result.push_back(a1);
    result.push_back(a2);

    return result;
}

template <typename T> 
std::vector<T> gen_vec(T a1, T a2, T a3)
{
    std::vector<T> result(1);

    result.push_back(a1);
    result.push_back(a2);
    result.push_back(a3);

    return result;
}

// and so on, boost stops at nine by default for their variadic templates

Usage:

func(gen_vec(1,2,3));
5
ответ дан 27 November 2019 в 21:49
поделиться

См. Функции с переменными числами в C, Objective-C, C ++ и D

Вам необходимо включить stdarg.h , а затем использовать va_list , va_start , va_arg и va_end , как пример в статье Википедии показывает. Это немного более громоздко, чем в Java или C #, потому что C и C ++ имеют только ограниченную встроенную поддержку varargs.

3
ответ дан 27 November 2019 в 21:49
поделиться

Если вас не волнует переносимость, вы можете перенести этот код C99 на C ++, используя выражения оператора gcc :

#include <cstdio>

int _sum(size_t count, int values[])
{
    int s = 0;
    while(count--) s += values[count];
    return s;
}

#define sum(...) ({ \
    int _sum_args[] = { __VA_ARGS__ }; \
    _sum(sizeof _sum_args / sizeof *_sum_args, _sum_args); \
})

int main(void)
{
    std::printf("%i", sum(1, 2, 3));
}

Вы могли бы сделать нечто подобное с лямбда-выражениями C ++ 0x, но используемая мной версия gcc (4.4.0) их не поддерживает.

1
ответ дан 27 November 2019 в 21:49
поделиться