19

例如,我已经知道stdarg.h在 c++ 中使用可变参数的函数的方法,如这里讨论的。我也知道 c++11 标准有可变参数模板,如此所述。

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

可变参数模板,也可用于创建接受可变数量参数的函数,通常是更好的选择,因为它们不会对参数的类型施加限制,不执行整数和浮点提升,并且是类型安全的.

是否可以?如果是,我该怎么做?

4

2 回答 2

30

使用可变参数模板编写一个函数很简单,它接受任意数量的参数。与一般模式的唯一区别是,具体类型用作第一个参数(头) - 而不是模板参数。下面的示例显示了一个函数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不幸的是,与常规函数一起使用时需要额外的花括号。如果使用了新的初始化语法,则构造函数不需要它们。

编辑:根据反馈重写答案。特别是我改变了两个解决方案/示例的顺序。

于 2012-04-06T14:21:36.190 回答
2

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

于 2012-04-06T14:02:28.053 回答