You can use a variadic function (like printf
), but you generally prefer not to.
You can take an initializer_list
as a parameter. This will let you take a braced list of items that can all be converted to a single type:
void f(std::initializer_list<int> l);
...which you could call something like:
f({1, 2, 3, 4});
There's also a ctor for std::vector
that takes an std::initializer_list
, so you can take a (reference to) a vector<T>
and accomplish roughly the same. Note, however, that (unlike most parts of C++) this doesn't support narrowing conversions, so for the f
above that requires int
s, you could get an error if you tried to pass (for example) a double
instead.
If you don't like the braces, or want to support the parameters being of different types, you can use a variadic template instead. For example here's a function I posted some time ago to take an arbitrary number of parameters of (nearly) arbitrary type, put them together into a string, and write the resulting string to a socket:
#include <sstream>
#include <string>
#include <iostream>
template <class T>
std::string stringify(T const &t) {
std::stringstream b;
b << t;
return b.str();
}
template<typename T, typename... Args>
std::string stringify(T arg, const Args&... args) {
return stringify(arg) + stringify(args...);
}
template<typename... Args>
void send_cmd(const Args&... args) {
std::string buffer = stringify(args...);
send(sock, buffer.c_str(), buffer.length(), 0);
}
int main() {
std::string three{" three"};
send_cmd("one: ", 1, " two: ", 2, three, "\n");
return 0;
}