Re: [boost] Re: Standard C Library and C++ / BOOST

Rob Stewart wrote:
From: "Reece Dunn" <msclrhd@hotmail.com>
The errorcheck class now has a policy-based implementation, so it would look something like:
template< typename ErrorStorage, typename ErrorMsgStorage > class errorcheck: public Storage, public MsgStorage { private: inline errorcheck( const Storage & s, const MsgStorage & ms ): Storage( s ), MsgStorage( ms ) { } public: inline errorcheck( typename Storage::error_type e ): Storage( e ), MsgStorage() { if( failed()) throw( errorcheck< Storage, MsgStorage >( *this, *this )); } };
which, IMHO, is more confusing than the straight throw( *this ), but does not use the copy constructor, relying instead of the fully constructed Storage and MsgStorage base classes.
I wouldn't call it confusing, though I'd expect that you'd need to document why you couldn't do the more obvious thing.
I mean confusing in that you have errorcheck( *this, *this ) so it is harder to see what is going on. I have added a comment line explaining why this is done and would also put this in the docs.
I do have to ask why the private ctor takes a MsgStorage object to copy since the MsgStorage in this case will be the default constructed base subobject created in the initializer list of the throwing ctor. As written, the second argument to that ctor is useless; the private ctor could default construct its MsgStorage subobject.
Actually, though, I had this in mind:
template <typename ES, typename MS> class error_check : public ES, public MS { error_check(typename ES::error_type e, std::nothrow_t) : ES(e) { }
public: error_check(typename ES::error_type e) : ES(e) { if (failed()) { throw error_check<ES,MS>(e, nothrow); } } };
What about when you use boost::policy::errormsg_storage instead of boost::policy::no_errormsg_storage? Doing this allows the following: typedef boost::errorcheck< boost::policy::error_storage<>, boost::policy::errormsg_storage > errorcheckmsg; try { errorcheckmsg em; em( "oops!" ) = -3; // note the special syntax } catch( errorcheckmsg em ) { std::cout << "error: " << em.get_msg() << '\n'; } resulting in "error: oops!" being outputted. Using your method, the message string will ont be passed and thus you would get "error: unspecified error"! That is why I implemented it as above.
(Note that you used "Storage" where you should have used "ErrorStorage" in the excerpt above. I just used abbreviations.)
That was my bad: ErrorStorage and Storage are the same. Regards, Reece _________________________________________________________________ Express yourself with cool emoticons - download MSN Messenger today! http://www.msn.co.uk/messenger

From: "Reece Dunn" <msclrhd@hotmail.com>
Rob Stewart wrote:
From: "Reece Dunn" <msclrhd@hotmail.com>
The errorcheck class now has a policy-based implementation, so it would look something like:
template< typename ErrorStorage, typename ErrorMsgStorage > class errorcheck: public Storage, public MsgStorage { private: inline errorcheck( const Storage & s, const MsgStorage & ms ): Storage( s ), MsgStorage( ms ) { } public: inline errorcheck( typename Storage::error_type e ): Storage( e ), MsgStorage() { if( failed()) throw( errorcheck< Storage, MsgStorage >( *this, *this )); } }; [snip] Actually, though, I had this in mind:
template <typename ES, typename MS> class error_check : public ES, public MS { error_check(typename ES::error_type e, std::nothrow_t) : ES(e) { }
public: error_check(typename ES::error_type e) : ES(e) { if (failed()) { throw error_check<ES,MS>(e, nothrow); } } };
What about when you use boost::policy::errormsg_storage instead of boost::policy::no_errormsg_storage? Doing this allows the following:
typedef boost::errorcheck< boost::policy::error_storage<>, boost::policy::errormsg_storage > errorcheckmsg;
try { errorcheckmsg em; em( "oops!" ) = -3; // note the special syntax } catch( errorcheckmsg em ) { std::cout << "error: " << em.get_msg() << '\n'; }
resulting in "error: oops!" being outputted. Using your method, the message string will ont be passed and thus you would get "error: unspecified error"! That is why I implemented it as above.
I didn't see anything like that in the code you showed. It was probably in the full implementation, but I was only looking at what's quoted above. Anyway, why must either constructor manage the string at this point? Why wouldn't the generation of the string occur at the time it is requested? That is, there is no string to copy if there is no string generated until the get_msg() mf is called. That mf can create the string (reusing it if already computed, of course). If you find your approach is still needed, no problem. I just wanted to be sure you understood what I had implied. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;
participants (2)
-
Reece Dunn
-
Rob Stewart