我目前正试图了解一些我可以通过可变参数模板支持做的事情。假设我有这样的函数 -
template <typename ... Args>
void foo(Args ... a)
{
int len = sizeof...(tail);
int vals[] = {a...};
/* Rest of function */
}
/* Elsewhere */
foo(1, 2, 3, 4);
这段代码有效,因为我事先假设参数是整数,但如果我提供其他东西,显然会失败。如果我知道参数包会提前包含一个特定类型,那么我可以通过某种方式在没有模板的情况下进行操作,并且有类似的东西 -
void foo(int ... a)
我试过这样做,但是编译器给出了关于foo是一个void字段的错误。我知道我也可以通过递归来访问包中的参数,但我不确定这会解决我的问题 - 即我希望能够获取相同类型的可变数量的参数。
答案 0 :(得分:12)
这应该有效:
void foo(int);
template<typename ...Args>
void foo(int first, Args... more)
{
foo(first);
foo(std::forward(more)...);
}
答案 1 :(得分: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;
}
如果您使用Visual Studio 2012,则可能需要Visual C++ Compiler November 2012 CTP。
编辑:如果您仍想使用可变参数模板,可以执行以下操作:
template <int ... Args>
void foo( )
{
int len = sizeof...(Args);
int vals[] = {Args...};
// ...
}
// And
foo<1, 2, 3, 4>();
但您必须记住,它不适用于float
和std::string
,例如:您将以'float': illegal type for non-type template parameter
结束。 float
作为non-type template parameter
是不合法的,这与精确度有关,浮点数无法精确表示,并且您引用相同类型的可能性取决于数字的表示方式。
答案 2 :(得分:2)
我目前正试图了解一些我可以使用可变参数模板支持做的事情。
假设您要尝试使用可变参数模板,而不是找到问题的任何解决方案,那么我建议您查看下面的代码:
#include <iostream>
template<int ...Values>
void foo2()
{
int len = sizeof...(Values);
int vals[] = {Values...};
for (int i = 0; i < len; ++i)
{
std::cout << vals[i] << std::endl;
}
}
int main()
{
foo2<1, 2, 3, 4>();
return 0;
}
foo2
和foo
之间的区别在于您在运行时将参数传递给foo
,在编译时传递给foo2
,因此对于每个参数集,使用,编译器将生成单独的foo2
函数体。
答案 3 :(得分:0)
最常见答案的一种变体,如果您愿意,则将拒绝隐式转换为true
:
exit
答案 4 :(得分:0)
在大多数情况下,使用具有相同类型参数包的可变参数模板是没有意义的,但在启用 c++11 的编译器中将是:
#include <iostream>
#include <tuple>
template <typename ... Args>
void foo(Args ... args) {
using type = typename std::tuple_element<0, std::tuple<Args...>>::type;
const auto len = std::tuple_size<std::tuple<Args...>> {};
type vals[] = {args...};
for (size_t it = 0; it < len; ++it) {
std::cout << vals[it] << std::endl;
}
}
int32_t main(int argc, char** argv) {
foo(1, 2);
foo(1.1, 2.2);
foo("1", "2");
return EXIT_SUCCESS;
}