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

Рейтинг: 4Ответов: 2Опубликовано: 09.03.2023

Задание:

Написать функцию sum с переменным числом параметров, которая находит сумму чисел типа int по формуле:
S=a1*a2+a2*a3+a3*a4+. . . . .
Написать вызывающую функцию main, которая обращается к функции sum не менее трех раз с количеством параметров 5, 10, 12

Не могу понять как вообще это cstdarg работает. Как я понимаю все это дело какой древний рудимент C? Какие есть альтернативы для решения задачи?

Ответы

▲ 4

Простейшее решение с stdarg:

int sum(int count, ...)
{
    va_list ap;
    va_start(ap,count);
    int Sum = 0;
    int a = va_arg(ap,int);
    for(int i = 1; i < count; ++i)
    {
        int b = va_arg(ap,int);
        Sum += a*b;
        a = b;
    }
    va_end(ap);
    return Sum;
}


int main(int argc, char * argv[])
{
    cout << sum(5,1,2,3,4,5) << endl;
}

С шаблонами набросал на коленке (т.е. не то, что допускаю — уверен, что может быть более красивый вариант) так:

int SumAux(int a0, int S, int x)
{
    return S + a0*x;
}

template<typename... Args>
auto SumAux(int a0, int S, int x, Args... args)
{
    S += a0 * x;
    return SumAux(x, S, args...);
}

template<typename... Args>
auto Sum(int x, int y, Args... args)
{
    return SumAux(x,0,y,args...);
}


int main(int argc, char * argv[])
{
    cout << Sum(1,2,3,4,5) << endl;
}

Чуть покороче — две SumAux заменяются одной:

template<typename... Args>
auto SumAux(int a0, int S, int x, Args... args)
{
    S += a0 * x;
    if constexpr (sizeof...(args) == 0) return S;
    else return SumAux(x, S, args...);
}
▲ 3

В случае одинаковых типов аргументов шаблона можно для простоты превращать их в какой-нибудь вектор:

#include <iostream>
#include <vector>

template <class... Args>
int sum(const Args&... args) {
    std::vector<int> a{static_cast<int>(args)...};
    const int count = a.size()-1;
    int out = 0;
    for (int i = 0; i < count; i++) {
        out+=a[i]*a[i+1];
    }
    return out;
}

int main()
{
    std::cout << sum(1,2,3,4,5) << std::endl;
    std::cout << sum(1,2,3.2,4,5) << std::endl;
    return 0;
}