簡體   English   中英

如何在不知道 C++ 中有多少可選 arguments 的情況下在循環中使用 va_arg?

[英]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
 
}

處理可變參數函數的三種方法:

  1. 要么有某種終止符,一個參數,其唯一含義是終止參數列表。

  2. 使第一個參數成為 arguments 傳遞的數量的計數。

  3. 某種參數匹配格式,例如printfscanf

對於您的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM