AMDG Dominique Devienne wrote:
// Context: retrieving all the rows (result set) from a given SQL query. // pseudo code of boilerplate code I keep repeating right now struct { int id; std::string name; } Row; void doit() { ResultSet rset = sql_exec("select id, name from t"); std::vector<Row> rows; while (rset.hasMoreRows()) { Row row; row.id = rset.get<int>(0); row.name = rset.get<const char*>(1); rows.push_back(row); } // process rows }
// Code I'd like to write instead void doit() { typedef boost::tuple<int, std::string> Row; std::vector<Row> rows; sql_get_rows("select id, name from t", rows); // optional arg to get only first N elements // process rows }
PS: returning the vector would be better, but because of the copy involved I guess I must pass it as a non-const ref instead, to fill it up. Will the new move semantic from the upcoming standard allow a function to return the vector without the copy? Just curious
In this case, I think Boost.Fusion can help (warning untested). #include <boost/fusion/include/for_each.hpp> #include <boost/fusion/include/boost_tuple.hpp> struct get_t { ResultSet& r; int& n; template<class T> void operator()(T& t) const { t = r.get<T>(n++); } }; template<Row> void get_rows(const char* query, std::vector<Row>& out) { ResultSet rset = sql_exec(query); while(rset.hasMoreRows()) { Row row; int n = 0; get_t getter = { rset, n }; boost::fusion::for_each(row, getter); out.push_back(row); } } In Christ, Steven Watanabe