Home > Enterprise >  How to expand the parameter package without recursion and not decomposing the elements into an array
How to expand the parameter package without recursion and not decomposing the elements into an array

Time:05-26

#include <iostream>
using namespace std;

template <class T, class... Other>
auto sum(T& first, Other... other)
{
    T mas[] = { other... };
    cout << "size: " << sizeof...(other) << endl;
    //T *f = other...;
    for (int m : mas)
        first  = m;
    return first;
}

int main()
{
    int summa = 0;
    sum(summa, 1, 2, 3, 4, 5, 6, 7);
    cout << "sum: " << summa << endl;

    return 0;
}

There is a short piece of code that outputs the following:

size: 7
sum: 28

The question is very simple and quick to get the same answer: How do I access element by element each variable accounting parameter other? I tried to create a pointer, but it constantly complains, in short, I don’t know how it looks syntactically.

I will make a reservation right away that I am not interested in how to decompose the elements into an array, I myself know how exactly I should refer to each element exactly other.

More precisely, how to expand the parameter package without recursion and not decomposing the elements into an array?

CodePudding user response:

How to expand the parameter package without recursion?

You have since C 17-fold expression for this needs. Using it, your function will simply be

template <class T, class... Other>
auto sum(T& first, const Other&... other)
{
    first = (other   ...   first);
    return first;
}

or without the redundant variable summa may be:

#include <type_traits>  // std::common_type_t

template <class... Other>
constexpr auto sum(const Other&... other) /* noexcept */
{
    return (other   ...   std::common_type_t<Other...>{});
}

See a demo


How do I access element by element each variable accounting parameter other?

You can apply fold expression along with an immediately invoking lambda function as follows:

template <typename ReType, typename... Other>
auto do_something_with_args(ReType& ret, Other&&... other)
{
    ([&ret](auto /* const& */ arg) {
        // do something with each arg and ret
        ret  = arg; // example
        std::cout << arg << '\n';
        }(std::forward<Other>(other)), ...);
    return ret;
}

See a demo


If you do not have access to C 17, then there are tweaks/ alternatives, which have been mentioned in the following posts:

CodePudding user response:

How about this solution?

template <class T, class... Other>
auto sum(T& first, Other... other)
{
    std::apply([&first](auto &&... i){(..., (first  = i)); }, std::make_tuple(std::forward<Other>(other)...));
    return first;
}
  • Related