Is it possible to write a c++ template function which takes a variable number of input variables of different types (number of input can be limited to say 10)?
For example take a function sql_exec() which executes an sql query string and saves the resulting rows in std vectors of the type supplied, i.e.
std::vector<double> x,y;
std::vector<std::string> s;
std::string query="select * from ...";
sql_exec(query, s,x,y); // error if less than 3 rows or conversion not possible
Now my naive approach would have been (limited to max 2 vectors)
struct null_type {};
template <typename T1=null_type, typename T2=null_type>
void sql_query(const std::string& query_str, std::vector<T1>& col1,
std::vector<T2>& col2) {
...
}
Of course that’s stupid as I didn’t tell the function about default arguments and we get
error: default template arguments may not be used in function templates
but actually it compiles with gcc and -std=c++0x. However, obviously sql_query() still doesn’t take variable length input and needs to be called with 2 vectors. Also, I’d like to have something portable working on most of the current compilers. Anything obvious I’ve overlooked? I know I can change the design and maybe use boost::tuple or something else but I’d have liked such a simple interface.
As said above, Boost.Preprocessor is the way to go if C++0x is not available, although it takes a while to get used to the syntax. The example below demonstrate the way Boost.Preprocessor can be used to define functions with variable (but limited) number of arguments.
The preprocessor expands this to:
Note, here we can’t use
BOOST_PP_REPEAT(MAX_PARAMS, SQL_QUERY, ~)as it starts replication with 0 parameters but we need to start with 1, that’s whyBOOST_PP_LOCAL_ITERATE()is needed which is more flexible.