Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
325 views
in Technique[技术] by (71.8m points)

c++ - read arguments from variadic template

I am a little confused about how can I read each argument from the tuple by using variadic templates.

Consider this function:

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

I call it from the main file like:

func(1,10,100,1000);

Now, I don't know how I have to extend the body of func to be able to read each argument separately so that I can, for example, store the arguments in an array.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You have to provide overrides for the functions for consuming the first N (usually one) arguments.

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 the variadic 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 next level down we expand the previous Rest and get:

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

And so on until Rest contains no members in which case unpacking it calls foo() (the overload with no arguments).


Storing the pack if different types

If you want to store the entire argument pack you can use an std::tuple

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

However this seems less useful.

Storing the pack if it's homogeneous

If all the values in the pack are the same type you can store them all like this:

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; 
        }
    );
}

However this seems even less useful.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...