Reputation: 56
Good evening,
I'm writing some classes, and I have a case where I would like a class method to take a variable number of arguments. I had issues getting this to compile, so I set up a very simple test case:
TestObject.h:
#include <ostream>
#include <stdarg.h>
class TestObject
{
public:
void test(int intCount, ...);
};
and TestObject.cpp:
#include "TestObject.h"
void TestObject::test(int intCount, ...)
{
va_list objList;
va_start objStart(objList, intCount);
int numArgs = va_arg(objList, int);
}
Finally, main.cpp:
#include<stdarg.h>
int maxof(int n_args, ...)
{
va_list ap;
va_start(ap, n_args);
int max = va_arg(ap, int);
for (int i = 2; i <= n_args; i++) {
int a = va_arg(ap, int);
if (a > max) max = a;
}
va_end(ap);
return max;
}
int main(int argc, char** argv)
{
int max = maxof(3, 1, 3, 2);
return 0;
}
main.cpp will compile just fine on its own, so I've narrowed it down to the case where the variable-length argument is in a class. When I add the classes to the project and try to compile, the build fails with the error C2065: '__crt_va_start': undeclared identifier. I'm building in Visual Studio 2015.
I'm aware that C++ has variadic templates, but whenever I get into template classes, I always seem to have to convert the class and usually related classes into header-only files and I'd like to avoid that. What I would probably do alternatively is just take a vector argument of some generic type.
Can someone tell me if I'm missing something here? Should I be able to compile and run a class method that has a variable-length argument in C++, or is this just something that's not supported?
Thanks!
Upvotes: 0
Views: 668
Reputation: 13708
Using a modern compiler you should not fall back to this old-style ellipsis syntax. For your purposes std::initializer_list is pretty good an alternative. Look how simple the code with it is:
#include <limits>
int maxof(std::initializer_list<int> args)
{
int max = std::numeric_limits<int>::min();
for(auto arg : args)
if(arg > max) max = arg;
return max;
}
int main(int argc, char** argv)
{
int max = maxof({3, 7, 1, 3, 2, 5});
return 0;
}
Upvotes: 2