Search code examples
c++performancecompilationc++20variadic-templates

Compilation differences between templated and non-templated variadic functions when arguments are only further passed (not accessed individually)


I am trying to understand what are the differences in compilation (and specially in compilation time) between having a templated versus non-templated variadic function in C++, in the special case when passed variadic arguments are just needed to be further passed to another function - not accessed individually.

For example, supposed we have this test-case class:

class ClassA 
{
    int _x = 0;
    double _y= 0.0;
    const char* _z = "";

    public:
    ClassA(int x, double y, const char* z) { _x=x; _y=y; _z=z;}

    void get() { printf("%i %f %s\n", _x, _y, _z); }
};

Next, we have a non-templated and a templated version of a function:

void fooVar(const auto & ...args)
{
    ClassA instance = ClassA(args...);
    instance.get();
}

template <typename... Args>
void fooTemp(const Args & ...args)
{
    ClassA instance = ClassA(args...);
    instance.get();
}

Both work as intended:

int main
{
    fooVar(10, 3.5, "example");
    fooTemp(10, 3.5, "example");
    return 0;
}

I am trying to understand how differently the compiler treats each function, and what are the pros and cons for compilation time performance when one has many and potentially more complex functions like those - when the passed variadic arguments are not expanded to be accessed individually but are rather just further passed along to some other functions.


Solution

  • void fooVar(const auto & ...args)
    

    Using the placeholder auto in the function parameter list makes the function an abbreviated function template, which makes it equivalent to a function template that uses a distinct type template parameter (possibly a pack) for each occurrence of auto. I.e. in this case it is exactly equivalent to

    template <typename... Args>
    void fooVar(const Args & ...args)
    

    Both are variadic templates with template parameter packs and function parameter packs. Neither are variadic functions which are something completely different. Variadic functions is a C concept that has nothing to do with templates. For example printf is a variadic function. They are typically only used in C++ to interface with C.