我已经知道stdarg.h
方法在c ++中有一个带变量参数的函数,例如here所讨论的。
我也知道c ++ 11标准有变量模板,如here所述。
但是在前面提到的两种方案中,我们都不知道(并且我们不能强迫)编译时间中的参数类型。我正在寻找的是将已知类型的变量参数传递给函数。我认为这可以做到,因为我读到了它here:
Variadic模板,也可用于创建带有可变数量参数的函数,通常是更好的选择,因为它们不对参数的类型施加限制,不执行整数和浮点促销,以及是安全的。
有可能吗?如果是,我该怎么做?
答案 0 :(得分:30)
直接编写一个带有可变参数模板的函数,它接受任意数量的参数。与一般模式的唯一区别在于,具体类型用作第一个参数(head) - 而不是模板参数。以下示例显示了一个函数foobar
,它接受任意数量的字符串。
// used for end of recursion - and for the empty arguments list
void foobar() { }
template <typename ...Tail>
void foobar(const std::string& head, Tail&&... tail)
{
// do something with head
std::cout << head << '\n';
// call foobar recursively with remaining arguments
foobar(std::forward<Tail>(tail)...);
}
foobar("Hello", "World", "...");
就个人而言,我更喜欢使用std::initializer_list
而不是变量模板。因为可变参数模板更复杂,需要额外的经验。使用std::initializer_list
,它可能如下所示:
void foobar(std::initializer_list<std::string> values)
{
for (auto& value : values) {
// do something with value
std::cout << value << '\n';
}
}
foobar({ "Hello", "World", "...", });
不幸的是,当std::initializer_list
使用常规函数时,需要额外的花括号。如果使用新的初始化语法,则构造函数不需要它们。
编辑:根据反馈重写了答案。特别是我改变了两个解决方案/例子的顺序。
答案 1 :(得分:2)
如果变量参数都是一种类型,您可以更改函数签名以获取这些类型的数组,而不是使用“...”。