Reputation: 906
I'm having trouble getting variable arguments to pass properly to a method - the method is intended to select a random value within a weighted distribution and return the index of the selected result.
An example usage would be:
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
}
The function is defined as follows:
#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)
}
When I run it in the debugger, the call to va_arg( argList, float )
is returning garbage values ( 2.0, 1.77499998, -1.08420217e-019 )
, rather than the values passed in ( 0.60f, 0.20f, 0.20f )
.
Any ideas what I'm doing wrong? As far as I can tell I'm following the spec exactly. I've been using http://www.cplusplus.com/reference/cstdarg/ as a reference.
Upvotes: 1
Views: 231
Reputation: 18751
If you are using c++ this is not really the correct way to do things anymore. Variadic templates are better than variable args (which are from c). Heres a better example of a variadic sum I did for class a while ago.
#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;
}
Variadic templates are types safe and produce more readable error free code imo.
Upvotes: 0
Reputation: 5998
The problem is float
is promoted to double
when it is passed through ...
so your loop should be
for ( int i = 0; i < weightCount; i++ ) {
weightTotal += va_arg( argList, double );
}
Upvotes: 1
Reputation: 87997
In a variadic function, float parameters will be converted to doubles. Try
weightTotal += va_arg( argList, double );
Upvotes: 4