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

So the errorcheck object will be in a half-constructed state. That is,
int will be constructed, but the errorcheck object isn't, therefore the int's destructor will be called, but errorcheck's deconstructor will not.
The solution would therefore be to throw an intermediate object, like
From: Rob Stewart <stewart@sig.com> From: "Reece Dunn" <msclrhd@hotmail.com> the the
Trules from the C++ Templates book by David Vandervoorde and Nico Josuttis. This would then get around the throwing in a constructor problem.
Why not throw a new errorcheck object using a private ctor that stores but doesn't check the return value?
That would work (I realised an implementation after the post). But this is what I was trying to achieve using the copy constructor (and copy assignment), since that copies the object, but does not throw on failure. 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. Regards, Reece _________________________________________________________________ Find a cheaper internet access deal - choose one to suit you. http://www.msn.co.uk/internetaccess

From: "Reece Dunn" <msclrhd@hotmail.com>
From: Rob Stewart <stewart@sig.com>
Why not throw a new errorcheck object using a private ctor that stores but doesn't check the return value?
That would work (I realised an implementation after the post). But this is what I was trying to achieve using the copy constructor (and copy assignment), since that copies the object, but does not throw on failure.
Right, but by creating a new object using only the error code, a value passed to the ctor, there's no illegality.
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 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); } } }; (Note that you used "Storage" where you should have used "ErrorStorage" in the excerpt above. I just used abbreviations.) -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;
participants (2)
-
Reece Dunn
-
Rob Stewart