I like vectors, and generally use them over arrays. For that reason I created a templated variadic function to initialize vectors (included below).
Header (.h):
template <typename T>
vector<T> initVector(const int argCount, T first, ...);
Source (.hpp):
template <typename T>
vector<T> initVector(const int argCount, T first, ...) {
vector<T> retVec;
retVec.resize(argCount);
if(argCount < 1) { ... }
retVec[0] = first;
va_list valist;
va_start(valist, first);
for(int i = 0; i < argCount-1; i++) { retVec[i+1] = va_arg(valist, T); }
va_end(valist);
return retVec;
}
It works great for most types (e.g. int, double…), but not for strings—as the compiler interprets them as ‘const char *’, thus
vector<string> strvec = initVector(2, "string one", "string two");
gives me the error:
error: conversion from ‘std::vector<const char*, std::allocator<const char*> >’ to non-scalar type ‘std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >’ requested
Is there any way to get the string arguments to be interpreted as strings without having to cast each one?
Because the type of the constant
"string one"isconst char*and notstd::stringthere needs to be a conversion.va_argcan not make this conversion, so we need a second template argument:Note that I made some changes, most notably change
resizetoreserve, to prevent unnecessary objects from being created.You can also simply use this (no risk of having number of elements messed up, and type safe):
Or use C++11 initializer lists:
For fun I made this little thing that is even neater and safer, but doesn’t generalize into an arbitrary amount of arguments. It works by overloading. Here are the first three overloads and example usage:
A full header (for up to 100 arguments) can be downloaded here: https://gist.github.com/3419369 .