From: Warren Young Date: April 8 2008 10:28pm Subject: RFC: Remove, change, or leave Query safe bool stuff alone? List-Archive: http://lists.mysql.com/plusplus/7570 Message-Id: <47FBF1AB.1060007@etr-usa.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit In another thread (http://lists.mysql.com/plusplus/7562) Dustin Moore discovered that the new safe bool stuff in Query isn't doing what it was designed to do because it conflicts with a similar mechanism in one of Query's base classes, basic_ios. (The Standard C++ Library derivation demon rises again...) I thought about changing the method to be operator void*() instead, overriding the basic_ios version. The code would then compile and do what was originally intended, but this has problems: 1. basic_ios::operator void*() isn't virtual, so it would be hidden. I'm not convinced that this is a serious problem due to the nature of this method, but the C++ FAQ says this is evil: http://www.parashift.com/c++-faq-lite/proper-inheritance.html#faq-21.1 2. I'm not sure testing the Query object in bool context makes a great deal of sense anyway. This operation doesn't tell you anything you can't figure out by some combination of testing the query *result* in bool context, catching exceptions, and calling Query::affected_rows(). It's just syntactic sugar. On the other hand, if I remove the safe bool stuff, it breaks the ABI yet again. Also, it allows calling the base class version which can result in a run-time failure by masking Query execution errors if you expected the test to check for them. I'm tempted to override operator void* but make it private so the build breaks in an "official" way. The decision rests on whether people are relying on "Query is-a ostream" in this regard: is anyone testing it in bool context, expecting to test only the status of the underlying ostream? Seems unlikely to me. So, here are the options: 1. Leave it alone, relying on the compile error to catch a likely bug. Downside: ugly, confusing error message. 2. Break the ABI, providing the current test through operator void*. Downside: fails if you test a Query object through a base class pointer. 3. Break the ABI, hiding operator void* as private in Query, so the test isn't available; the only way to find success is through Query's existing interfaces, not through the base class interface. Downside: breaks the is-a relationship between Query and ostream still further.