Vararg functions are dangerous, they are typeless and easy to abuse. You should avoid them whenever possible. If you provide vararg functions in your interface for other coders then they will often make difficult-to-find mistakes. If you are passing variable number of arguments then do that in one of the following ways:
- pass a whole container if you have to pass a copy of the arguments
- pass a (const) reference to a container if you don't have to copy the items
- the best solution if you don't have to copy the items: pass in the begin and end iterators of your data
Declare your variables in the innermost scope possibly where you use it the first time, and not at the beginning of your function body!
#include <cstdio>
#include <vector>
#include <cassert>
template <typename ItemType, typename Iterator>
ItemType Average(Iterator first, Iterator last)
{
assert(first < last);
ItemType count = (ItemType)(last - first);
ItemType sum = ItemType();
while (first < last)
sum += *first++;
return sum / count;
}
int main()
{
static const double DOUBLE_ARRAY[] = { 1.1, 3.3, 4.4 };
static const int INT_ARRAY[] = { 1, 3, 4 };
printf("float array average: %Lf\n", Average<double>(DOUBLE_ARRAY, DOUBLE_ARRAY+sizeof(DOUBLE_ARRAY)/sizeof(DOUBLE_ARRAY[0])));
printf("int array average: %d\n", Average<int>(INT_ARRAY, INT_ARRAY+sizeof(INT_ARRAY)/sizeof(INT_ARRAY[0])));
std::vector<float> floats;
printf("Please enter float values and then enter X to print the average of the values entered!\n");
for (;;)
{
char buf[0x100];
if (!fgets(buf, sizeof(buf), stdin))
return 1;
if (!strcmp("x\n", buf) || !strcmp("X\n", buf))
break;
float f;
if (1 != sscanf(buf, "%f", &f))
printf("Invalid float value: %s\n", buf);
else
floats.push_back(f);
}
if (floats.empty())
printf("There are no items.\n");
else
printf("The average of %d float values: %f\n", (int)floats.size(), Average<float>(floats.begin(), floats.end()));
return 0;
}