Read arguments from a variation template

I am a bit confused about how I can read each argument from a tuple using variable templates.

Consider this function:

template<class...A> int func(A...args){
int size = sizeof...(A);
.... }

I call it from the main file, for example:

func(1,10,100,1000);

Now I do not know how I can expand the body functo read each argument separately, so that I can store, for example, the arguments in an array.

+7
source share
4 answers

You need to provide overrides for functions to use the first arguments N(usually one).

void foo() {
   // end condition argument pack is empty
}

template <class First, class... Rest> 
void foo(First first, Rest... rest) {
    // Do something with first
    cout << first << endl; 

    foo(rest...); // Unpack the arguments for further treatment
}

When you unpack a variable parameter, it finds the next overload.

Example:

foo(42, true, 'a', "hello");
// Calls foo with First = int, and Rest = { bool, char, char* }
// foo(42, Rest = {true, 'a', "hello"}); // not the real syntax

Then, on the next level, we expand the previous one Restand get:

foo(true, Rest = { 'a', "hello"}); // First = bool

, Rest , foo() ( ).


,

, std::tuple

template <class... Pack>
void store_pack(Pack... p) {
    std::tuple<Pack...> store( p... );
    // do something with store
}

.

,

, :

vector<int> reverse(int i) {
    vector<int> ret;
    ret.push_back(i);
    return ret;
}

template <class... R>
vector<int> reverse(int i, R... r) {
    vector<int> ret = reverse(r...);
    ret.push_back(i);
    return ret; 
}

int main() {
    auto v = reverse(1, 2, 3, 4);
    for_each(v.cbegin(), v.cend(), 
        [](int i ) { 
            std::cout << i << std::endl; 
        }
    );
}

.

+11

, ( ):

template <class T, class ...Args>
void foo(const T& first, const Args&... args)
{
    T arr[sizeof...(args) + 1] = { first, args...};
}

int main()
{
    foo(1);
    foo(1, 10, 100, 1000);
}

, , boost::any, , , ( ).


Edit: STL, std::initializer_list<T>. , Motti :

#include <vector>
#include <iostream>
#include <iterator>

template <class Iter>
std::reverse_iterator<Iter> make_reverse_iterator(Iter it)
{
    return std::reverse_iterator<Iter>(it);
}

template <class T>
std::vector<T> reverse(std::initializer_list<T> const & init)
{

    return std::vector<T>(make_reverse_iterator(init.end()), make_reverse_iterator(init.begin()));
}

int main() {
    auto v = reverse({1, 2, 3, 4});
    for (auto it = v.begin(); it != v.end(); ++it) {
        std::cout << *it << std::endl;
    }
} 
+3

, , std::common_type<>

template<class ...A> void func(A ...args){
   typedef typename std::common_type<A...>::type common;
   std::array<common, sizeof...(A)> a = {{ args... }};
}

, , func(std::string("Hello"), "folks") std::string.

+2

If you need to store the arguments in an array, you can use the array boost::anyas follows:

template<typename... A> int func(const A&... args)
{
  boost::any arr[sizeof...(A)] = { args... };
  return 0;
}
+1
source

All Articles