从variadic模板中读取参数

sam*_*ami 8 c++ c++11

我对如何通过使用可变参数模板从元组中读取每个参数感到有点困惑.

考虑这个功能:

template<class...A> int func(A...args){
int size = sizeof...(A);
.... }
Run Code Online (Sandbox Code Playgroud)

我从主文件中调用它,如:

func(1,10,100,1000);
Run Code Online (Sandbox Code Playgroud)

现在,我不知道如何扩展主体func以便能够单独读取每个参数,以便我可以,例如,将参数存储在数组中.

Mot*_*tti 14

您必须为使用第一个N(通常是一个)参数的函数提供覆盖.

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
}
Run Code Online (Sandbox Code Playgroud)

解压缩variadic参数时,它会找到下一个重载.

例:

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
Run Code Online (Sandbox Code Playgroud)

然后下一级我们扩展前一个Rest并得到:

foo(true, Rest = { 'a', "hello"}); // First = bool
Run Code Online (Sandbox Code Playgroud)

依此类推,直到不Rest包含任何成员,在这种情况下解包它调用foo()(没有参数的重载).


如果不同类型存储包

如果要存储整个参数包,可以使用 std::tuple

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

然而,这似乎不太有用.

如果包装均匀,则存放包装

如果包中的所有值都是相同类型,则可以将它们全部存储为:

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; 
        }
    );
}
Run Code Online (Sandbox Code Playgroud)

然而,这似乎没那么有用.