如何在 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);
那个蜜蜂集,可变参数是一种非常不安全的变量传递方式。在您的示例中,如果有人将 a
、b
和 c
的类型更改为另一种类型,您将 运行 陷入严重的问题,因为 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';
}
我正在尝试创建一个函数,使用 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);
那个蜜蜂集,可变参数是一种非常不安全的变量传递方式。在您的示例中,如果有人将 a
、b
和 c
的类型更改为另一种类型,您将 运行 陷入严重的问题,因为 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';
}