已知类型的C++可变参数函数模板

znb*_*nby 11 c++ templates variadic-functions variadic-templates c++11

我目前正试图了解一些我可以使用可变参数模板支持做的事情.假设我有这样的功能 -

template <typename ... Args>
void foo(Args ... a)
{
    int len = sizeof...(tail);
    int vals[] = {a...};
    /* Rest of function */
}

/* Elsewhere */
foo(1, 2, 3, 4);
Run Code Online (Sandbox Code Playgroud)

这段代码有效,因为我事先假设参数是整数,但如果我提供其他东西,显然会失败.如果我知道参数包将提前包含一个特定的类型,有没有一种方法,我可以做没有模板,并有类似的东西 -

void foo(int ... a)
Run Code Online (Sandbox Code Playgroud)

我试过这样做,但是编译器给出了关于foo是一个void字段的错误.我知道我也可以通过递归来访问包中的参数,但我不确定这会解决我的问题 - 即我希望能够采用相同类型的可变数量的参数.

Yon*_*ong 13

这应该工作:

void foo(int);

template<typename ...Args>
void foo(int first, Args... more)
{
   foo(first);
   foo(std::forward(more)...);
}
Run Code Online (Sandbox Code Playgroud)

  • `std::forward` 是多余的,除非使用 `Args&amp;&amp;` 而不是 `Args` (2认同)

Pie*_*aud 6

如果您之前知道类型,则可以使用函数重载std:initializer_list:

#include <initializer_list>
#include <iostream>

void foo( std::initializer_list<int> l )
{
    for ( auto el : l )
        // do something
}

void foo( std::initializer_list<float> l )
{
}

void foo( std::initializer_list<std::string> l )
{
}

int main()
{
    foo( {1, 2, 3, 4 } );
    foo( {1.1f, 2.1f, 3.1f, 4.1f } );
    foo( { "foo", "bar", "foo", "foo" } );
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果使用Visual Studio 2012,则可能需要Visual C++编译器2012年11月CTP.

编辑:如果您仍想使用可变参数模板,您可以:

template <int ... Args>
void foo( )
{
    int len = sizeof...(Args);
    int vals[] = {Args...};
    // ...
}

// And

foo<1, 2, 3, 4>();
Run Code Online (Sandbox Code Playgroud)

但是你必须记住它不能floatstd::string你一起工作,例如:你将以此结束'float': illegal type for non-type template parameter.float作为a是不合法的non-type template parameter,这与精度有关,浮点数不能精确表示,并且您引用相同类型的可能性取决于数字的表示方式.