[英]How can I use va_arg in a loop without knowing how many optional arguments there are in C++?
I want to write a function which takes at least two integer and returns the sum of all integer passed to the function:
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 循环中的表达式必须如何看起来才能使循环继续,直到所有可选的 arguments 都被添加到总和中。 在不知道有多少可选 arguments 被传递给 function 的情况下,我将如何实现这一点? function 调用如下所示:
sumOfAtLeastTwoIntegers(2,3,4,5,1,0,200);
处理变量arguments一般有两种方式,前置知识和后置知识。
预知识就像printf("%d %c\n", 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';
}
这不一定像变量 arguments 一样快,但我现在的默认 position 通常是首先优化可读性:-)
我建议使用如下的可变参数模板。 它只有在你至少给它两个整数时才有效。 所有的参数也必须是整数。
#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
}
处理可变参数函数的三种方法:
要么有某种终止符,一个参数,其唯一含义是终止参数列表。
使第一个参数成为 arguments 传递的数量的计数。
某种参数匹配格式,例如printf
或scanf
。
对于您的 function,前两个变体都可能是很好的解决方案(取决于参数中允许的值范围)。
使用第一个参数作为“输入大小”,就像使用常规 arrays 一样,尤其是在 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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.