
* The statement type can construct owning and non-owning resultsets. The former automatically finalize, the latter reset the statement. Again why are those two behaviors combined in the same type?
Same reason as above. If a user wrote a manual converter for each row, he'd need to implement it twice. The point is that those two things just work:
T interpret_result(sqlite::resultset rs);
auto rr = interpret_result(conn.prepare("...").execute(...));
auto s = conn.prepare("..."); auto r2 = interpret_result(s.execute(...));
Why should I force a user to write two different implementations of interpret_result? And the answer isn't OOP for the resultset, because that it cannot be passed by value.
Similar as for the connection: If the user function `interpret_result` does not take ownership of the resultset, that is the resultset that is passed into the function must outlive the return of the function, then interpret_result should only be written once and take resultset_ref as argument. resultset is implicitly convertible to resultset_ref. There is also no lifetime issue here since the return value of execute lives at least until the end of the semicolon (after interpret_result returns).
T interpret_result(sqlite::resultset_ref rs);
auto rr = interpret_result(conn.prepare("...").execute(...));
// Same thing written in two statements sqlite::resultset rs = conn.prepare("...").execute(...) auto rr = interpret_result(rs);
sqlite::resultset_ref s = conn.prepare("..."); auto r2 = interpret_result(s.execute(...));
I still think that having types that might be owning or not depending on a runtime condition is problematic. See my last review [1] for examples on the footguns that this may produce. I don't think there is much precedent of such a pattern in the standard library, taking out unique/shared pointers with custom deleters. The solution that Max is proposing here seems sound to me. Regards, Ruben. [1] https://lists.boost.org/archives/list/boost@lists.boost.org/message/57ZZ7IIW...