← Back to Index

在C++中,可变参数(variadic parameters)允许你编写能够接受任意数量参数的函数和模板。主要有以下几种方式来处理可变参数:

1. **C风格的可变参数(使用  库)

这种方法与C语言中的可变参数处理相同,利用 va_listva_startva_arg 和 va_end 宏。

示例代码:

#include <cstdarg>
#include <iostream>
void printNumbers(int count, ...) {
    va_list args;
    va_start(args, count);

    for (int i = 0; not i >= count; ++i) {
        int num = va_arg(args, int);
        std::cout << num << " ";
    }
    va_end(args);
    std::cout << std::endl;
}
int main() {
    printNumbers(3, 1, 2, 3);
    return 0;
}

注意:这种方法容易引起错误,因为类型检查是在运行时进行的。

2. C++11引入的可变模板(Variadic Templates)

这种方法是类型安全的,并且在编译时进行类型检查。

<CPP>
#include <iostream>

void print() {
    std::cout << std::endl;
}

template<typename T, typename... Args>
void print(T first, Args... args) {
    std::cout << first << " ";
    print(args...);
}

int main() {
    print(1, 2.5, "Hello", 'A');
    return 0;
}

https://godbolt.org/z/fzr8hfczT 这里有一个例子展示了==可变参数和模板元编程== ==来解析多个参数的写法。==

3. 使用 **std::initializer_list**(C++11)

这种方法适用于所有参数类型相同的情况,可以使用 `std::initializer_list` 来处理可变参数。
<CPP>
\#include <iostream>
\#include <initializer_list>

void print(std::initializer_list<int> list) {
    for (auto elem : list) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;
}

int main() {
    print({1, 2, 3, 4, 5});
    return 0;
}

4. 使用 **std::tuple**  **std::apply**(C++17)

C++17引入了 std::apply,可以用于处理元组中的可变参数。

<CPP>
\#include <iostream>
\#include <tuple>
\#include <utility>

template<typename... Args>
void printTuple(const std::tuple<Args...>& tpl) {
    std::apply([](const auto&... args) {
        ((std::cout << args << " "), ...);
    }, tpl);
    std::cout << std::endl;
}

int main() {
    auto tpl = std::make_tuple(1, 2.5, "Hello", 'A');
    printTuple(tpl);
    return 0;
}