如何在 C++ 中分配 variadic/variable 个参数

How to assign variadic/variable arguments in C++

我正在尝试创建一个函数,使用 variadic/variable 输入参数将默认值或输入值分配给多个(标量)参数:

void set_params(const vector<double> &input, int n, ...) {  
  va_list args;
  va_start (args, n);
  for (int i = 0; i < n; i++) {
    if (i < input.size()) {
      va_arg(args, int) = input[i];
    }
  }
  va_end(args);
}

int a = 1, b = 2, c = 3;
set_params({10, 20}, 3, a, b, c);

但是,我在作业中遇到错误 va_arg(args, int) = input[i]。是否有可能以某种方式使用可变参数进行赋值,或者是否有更好的方法来实现这一点?

如果要更改作为函数参数传递的变量,则必须使用指针或引用。例如,以下函数将无效,因为 x 是按值传递而不是按引用传递。

void set_zero(int x) {
    x = 0;
}

在 C++ 中,您有两个选项可以通过引用传递某些内容。传递 指针 或传递 左值引用 :

void set_zero(int *x) {
    *x = 0;
}

void set_zero(int &x) {
    x = 0;
}

这两个都会将原始变量更改为零。我还没有找到通过可变函数调用传递左值引用的方法,所以我建议您使用指针。在您的情况下,代码看起来像

void set_params(const vector<double> &input, int n, ...) {  
    va_list args;
    va_start (args, n);
    for (int i = 0; i < n; i++) {
        if (i < input.size()) {
            va_arg(args, int*) = input[i];
        }
    }
    va_end(args);
}

int a = 1, b = 2, c = 3;
set_params({10, 20}, 3, &a, &b, &c);

那个蜜蜂集,可变参数是一种非常不安全的变量传递方式。在您的示例中,如果有人将 abc 的类型更改为另一种类型,您将 运行 陷入严重的问题,因为 set_params 函数不再匹配传递的变量类型。您可以通过例如更安全的方式完成整个功能也对指针使用向量。

template<typename T>
void set_params(const vector<T> &input, const vector<T*> &variables) {
    for ( int i = 0; i < variables.size(); i++ ) {
        if ( i < input.size() ) {
            *variables[i] = input[i];
        } else {
            break;
        }
    }
}

int a = 1, b = 2, c = 3;
set_params<int>({10,20}, {&a, &b, &c});

C++ 没有使用 C 的 va_ 东西,而是有自己的可变参数模板参数,which you should preferably use

我不是这方面的专家,但它看起来有点像

#include <vector>
#include <iostream>

template <typename... Arg>
void set_params(const std::vector<double> &input, Arg&... arg) {
    unsigned int i{0};
    (
        [&] {
            if (i < size(input)) {
                arg = input[i++];
            }
        }(), // immediately invoked lambda/closure object
        ...); // C++17 fold expression
}

int main() {
    int a = 1, b = 2, c = 3;
    set_params({10, 20}, a, b, c);

    std::cout
        << a << ' '
        << b << ' '
        << c << '\n';
}