Is there a compiler flag or technique to force the generation of one non-variadic function for each call to a variadic function template with a unique signature?
In the following example, the compiler creates variadic templates with signatures int (int, float, double)
, int (float, double)
and int (double)
.
#include <iostream>
using namespace std;
template<class IntT, class argsf>
IntT SumArgs(const argsf& firstArg)
{
return static_cast<IntT>(firstArg);
}
template<class IntT, class argsf, class ...argst>
IntT SumArgs(const argsf& firstArg, const argst&... restArgs)
{
return static_cast<IntT>(firstArg + SumArgs<IntT>(restArgs...));
}
int main()
{
cout<<"Sum result: " << SumArgs<int>(1, 2.f, 3.5);
return 0;
}
The first two remain variadic. However, in some circumstances, it might be desirable to avoid the overhead of variadic functions and instead create a unique function definition for each signature listed above. Is there a way to get compilers to do this? The alternative is to write versions of the function that explicitly use 0, 1, 2 ... n arguments for some reasonably large n and duplicate the code by hand, but ideally the compiler could do this heavy-lifting for us.
C++17 introduces fold expressions which are (hopefully) exactly what you are looking for:
template <class R, class... Args>
constexpr R SumArgs(const Args&... args)
{
return static_cast<R>((args + ...)); // fold expression
}
If you don't want to use variadic templates, you can use an initializer_list
:
template <class R, class T>
constexpr R SumArgs(std::initializer_list<T> args)
{
return std::accumulate(args.begin(), args.end(), R{});
}