Search code examples
c++constructorvariadic-functionsvariadic

What is the use of variadic constructor in C++?


Consider following program:

#include <iostream>
struct Test
{
    Test(...)
    {
        std::cout<<"Variadic constructor\n";
    }
};
int main()
{
    Test t;
    t={3,4,5};
}

I think it is variadic constructor. Does the C++ standard says that constructor can be variadic? What is the use of such constructor? What is the rationale for allowing variadic constructor?


Solution

  • Let's try to answer your questions one by one:

    I think it is variadic constructor.

    You are correct.

    Does the C++ standard says that constructor can be variadic?

    IANALL, but, I think so. Why not? Constructor is just a (member) function.

    What is the use of such constructor?

    Like any other variadic function - to pass a variable number of arguments. It also has the same problems, mostly no type safety as any other variadic function. For example, let's say you need a list of (C) strings, you could do something like See live demo here.

    #include <iostream>
    #include <cstdarg>
    struct Test
    {
        Test(int n,...)
        {
            va_list va;
            va_start(va, n);
            for (int i = 0; i < n; ++i) {
                 char const *s = va_arg(va, char*);
                 std::cout<<"s=" << s << std::endl;
            }
            va_end(va);
        }
    };
    int main()
    {
         Test t{3, "3","4","5"};
    }
    

    Keep in mind that for this to work, you need at least one "non-variadic" parameter. So a "pure variadic" constructor, like the one you show, doesn't make much sense in portable C++ code. For any particular platform, you may know how to access the parameters even without the non-variadic parameter, so, this might work:

         Test t={"3","4","5", NULL};
    

    What is the rationale for allowing variadic constructor?

    "It's C compatible and someone might have a use of it", I guess. If you know your way around <cstdarg>, it can be an effective tool. Of course, with C++11, you should most probably use variadic templates / perfect forwarding and initialization lists instead. But, with C++98 you didn't have these tools.