Better approach would be get rid of variadic arguments. This was inherited from C and it is a good practice to avoid it as much as possible.
Now your example avg(4,myArray[5]) is a bit fuzzy. I assume, that first argument defines how much items must be taken from array and second argument you planned to pass just an array. I assume this index operator is typo or limping method showing array size.
So you expect something like this:
int avg(int count, ...)
{
int sum = 0;
std::va_list args;
va_start(args, count);
for (int i = 0; i < count; ++i) {
sum += va_arg(args, int);
}
va_end(args);
return sum / count;
}
template <size_t N, size_t... I>
int avg_helper(size_t count, const int (&arr)[N], std::index_sequence<I...>)
{
return avg(count, arr[I]...);
}
template <size_t N>
int avg(int count, const int (&arr)[N])
{
if (count > N)
throw std::invalid_argument { "to large count passed" };
return avg_helper(count, arr, std::make_index_sequence<N> {});
}
https://godbolt.org/z/7v1n7zaWq
Now note that in overload resolution variadic function is match as a last one. So when compiler can match template it will select it instead variadic function.
Note there is a trap. If you will pass a pointer (for example array decay) variadic argument function will kick in again. So as protection I've added extra overload which will trigger static_assert warning about array decay.
...but I was wondering if I could do it without changing the function.avg(4,myArray[5])looks strange, please clarify that., it would be best to provide unit test which should pass.