具有已知类型的可变数量参数的函数,c ++ 11方式

时间:2012-04-06 13:52:56

标签: c++ templates c++11 variadic-templates variadic-functions

我已经知道stdarg.h方法在c ++中有一个带变量参数的函数,例如here所讨论的。 我也知道c ++ 11标准有变量模板,如here所述。

但是在前面提到的两种方案中,我们都不知道(并且我们不能强迫)编译时间中的参数类型。我正在寻找的是将已知类型的变量参数传递给函数。我认为这可以做到,因为我读到了它here

  

Variadic模板,也可用于创建带有可变数量参数的函数,通常是更好的选择,因为它们不对参数的类型施加限制,不执行整数和浮点促销,以及是安全的。

有可能吗?如果是,我该怎么做?

2 个答案:

答案 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)

如果变量参数都是一种类型,您可以更改函数签名以获取这些类型的数组,而不是使用“...”。