2013-05-09 24 views
1

我無法獲取可變參數以正確傳遞給方法 - 該方法旨在選擇加權分佈內的隨機值並返回選定的結果。帶可變參數的C++方法(...)報告不正確的參數值

一個示例用法是:

int pickupType = randomManager->ByWeights(3, 0.60f, 0.20f, 0.20f); 
switch(pickupType) { 
    // ... pickupType should be 0 to 2, which we can then branch on 
} 

該函數定義如下:

#include <cstdarg> 

int RandomManager::ByWeights(int weightCount, ...) { 

    va_list argList; 

    // Get the total of all weights 
    va_start(argList, weightCount); 
    float weightTotal = 0; 
    for (int i = 0; i < weightCount; i++) { 
     weightTotal += va_arg(argList, float); 
    } 
    va_end(argList); 

    // Roll a number in that range 
    // ... (further processing - problem occurs above) 
} 

當我在調試器中運行,該呼叫到va_arg(argList, float)將返回無用值(2.0, 1.77499998, -1.08420217e-019),而比在(0.60f, 0.20f, 0.20f)中傳遞的值。

任何想法我做錯了什麼?據我所知,我完全按照規範。我一直在使用http://www.cplusplus.com/reference/cstdarg/作爲參考。

+0

是否使用C++ 11 float提升爲double?如果是這樣,你應該用類型安全的可變參數模板替換它。雖然我在這裏看不到任何問題。 – chris 2013-05-09 20:47:16

+0

Eww,var-args總是讓我生病。很多方式可能會失敗,但卻非常驚人。 – 2013-05-09 20:48:15

回答

5

在一個可變參數函數中,浮點參數將被轉換爲雙精度。嘗試

weightTotal += va_arg(argList, double); 
+0

你習慣了可變參數模板後忘記了什麼。 C有時可能會如此愚蠢:/ – chris 2013-05-09 20:49:30

+0

謝謝 - 沒有意識到雙重轉換,解決了它。 – QuadrupleA 2013-05-09 21:23:38

0

如果您使用的是C++,這不是真正做事的正確方法。變量模板比變量參數(來自c)要好。這是一個更好的例子,我剛纔爲班級做了一個可變數量的總和。

#include <iostream> 

namespace cs540 { 
    template <typename T> 
    const T & sum(const T & v) { 
     return v; 
    } 

    template <typename T, typename T2, typename ... Ts> 
    T sum(const T & v, const T2 & w, const Ts & ... params) { 
     return sum(w+v,params...); 
    } 
} 

int main() { 
    using namespace cs540; 
    using namespace std; 
    cout << sum(1.1,2,3,4,6,8,9,1.1) << endl; 
} 

變量模板是類型安全的,併產生更具可讀性的無錯誤代碼imo。

+0

也更長 - 因爲它是一個運行時模板,它將不得不創建多個版本,每個版本都有一個版本,不是嗎?如果是這樣,那麼va_args仍然有時應該被使用。編輯:bleh,我說運行時間,但意味着編譯時間。保持它,因爲評論的後續被我困惑。 – 2013-05-09 20:51:46

+0

@GabeSechan,它爲每種不同類型的呼叫創建一個定義,以便爲您所需要的內容重載,而不再是其他內容。這一切都發生在編譯時。 – chris 2013-05-09 20:54:05

+0

是的,但我認爲大多數需要可變參數的函數應該很簡單,對於更復雜的函數,您應該在某個點使用數組。 – aaronman 2013-05-09 20:54:06

1

的問題時,它是通過...

傳遞,因此你的循環應該是

for (int i = 0; i < weightCount; i++) { 
    weightTotal += va_arg(argList, double); 
}