如何在不知道C++中有多少可选参数的情况下在循环中使用va_arg?

How can I use va_arg in a loop without knowing how many optional arguments there are in C++?

本文关键字:循环 情况下 va arg C++ 不知道 多少 参数      更新时间:2023-10-16

我想编写一个函数,它至少接受两个整数并返回传递给该函数的所有整数的总和:

int sumOfAtLeastTwoIntegers(int a, int b, ...){

int sum = a+b;
va_list ptr;
va_start(ptr,b);
for(){
sum += va_arg(ptr, int)
}
va_end(ptr);
return sum;
}

我想知道 for 循环中的表达式必须如何使循环继续,直到将所有可选参数添加到总和中。 在不知道向函数传递了多少可选参数的情况下,我将如何实现这一点? 函数调用如下所示:

sumOfAtLeastTwoIntegers(2,3,4,5,1,0,200);

通常有两种方法来处理变量参数,前知识与后知识。

预知就像printf("%d %cn", anInt, aChar)一样,前面有一个论点,你可以用它来弄清楚还剩下多少。这方面的一个例子是:

int sumOfInts(size_t count, int a, ...); // Needs "count" integers.
int eleven = sumOfInts(2, 4, 7);

后知识要求您有一个哨兵值来告诉您何时停止,例如:

int sumOfNonZeroInts(int a, ...); // Needs non-zero integers, stops at 0.
int eleven = sumOfInts(4, 7, 0);

你可能要考虑的另一件事是避开变量参数列表,C++中有更多表达方式可以做你想做的事情,例如向量。下面提供了一种方法来执行此操作:

#include <iostream>
#include <vector>
template<typename T> T sumOf(const std::vector<T> &vec) {
T acc = T();
for (const T &item: vec)
acc += item;
return acc;
}
int main() {
auto eleven = sumOf<int>({4, 7}); 
std::cout << "Four plus seven is equal to " << eleven << 'n';
}

这不一定像变量参数那样,但我现在的默认立场是通常首先优化可读性:-(

我建议使用如下所示的可变参数模板。仅当您至少给它两个整数时,它才有效。所有的参数也必须是整数。

#include<iostream>
#include <type_traits>
template< typename ... Args>
std::enable_if_t<std::is_same_v<std::common_type_t<Args...>, int>, int>
sum(int arg1, Args...args)
{
return (args+...+arg1);
}
int main(){
std::cout << sum(1,2);//working
std::cout << sum(1,.2);//compile error
std::cout << sum(1);//compile error

}

有三种方法可以处理变量参数函数:

  1. 两者都有某种终止,一个参数,其唯一含义是终止参数列表。

  2. 使第一个参数成为传递的参数数的计数。

  3. 某种参数匹配格式,例如printfscanf.

对于您的函数类型,前两个变体都可以是很好的解决方案(取决于参数中允许的值范围(。

使用第一个参数作为"输入大小",就像使用常规数组一样,尤其是在 C 中。

int sumOfAtLeastTwoIntegers(int howMany, ...) {

int sum = 0
va_list ptr;
va_start(ptr,b);
while(howMany--){
sum += va_arg(ptr, int)
}
va_end(ptr);
return sum;
}
相关文章: