From: DeMarcus on 8 May 2010 02:21 Hi, I have a problem. I want to throw ExceptionA derived from Exception, i.e. struct ExceptionA : Exception { }; ExceptionA, ExceptionB, ExceptionC, etc. shall be able to attach text to the exception directly at construction via function chaining, i.e. throw ExceptionA().addText( "Hello" ).addText( "World" ); The quick way to implement that would be the following. struct Exception { Exception& addText( const std::string& str ) { // Add str to some private string. return *this; } }; Now, the problem comes with the throw. throw ExceptionA().addText( "Hello" ).addText( "World" ); That will slice the exception and not throw an ExceptionA but instead just a plain Exception since that is what addText() returns. My solution to this problem is written below, but before you scroll down and get biased; how would you solve this? Thanks, Daniel My solution: Create a mixin to provide the addText() like this. struct Exception { void addExceptionText( const std::string& str ) { // Add str to some private string. } }; template<class T> struct ExceptionTextMixin { T& addText( const std::string& str ) { // Use CRTP. static_cast<T*>(this)->addExceptionText( str ); return *static_cast<T*>(this); } }; Now, for each ExceptionA, ExceptionB, ExceptionC, etc. struct ExceptionA : Exception, ExceptionTextMixin<ExceptionA> { }; Is it ok to use mixins and CRTP for problems like this, or will I get in trouble later? -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: AnonMail2005 on 9 May 2010 08:06 On May 8, 1:21 pm, DeMarcus <use_my_alias_h...(a)hotmail.com> wrote: > Hi, > > I have a problem. I want to throw ExceptionA derived from Exception, i.e. > > struct ExceptionA : Exception > { > > }; > > ExceptionA, ExceptionB, ExceptionC, etc. shall be able to attach text to the exception directly at construction via function chaining, i.e. > > throw ExceptionA().addText( "Hello" ).addText( "World" ); > > The quick way to implement that would be the following. > > struct Exception > { > Exception& addText( const std::string& str ) > { > // Add str to some private string. > return *this; > } > > }; > > Now, the problem comes with the throw. > > throw ExceptionA().addText( "Hello" ).addText( "World" ); > > That will slice the exception and not throw an ExceptionA but instead just a plain Exception since that is what addText() returns. > > My solution to this problem is written below, but before you scroll down and get biased; how would you solve this? > > Thanks, > Daniel > > My solution: > > Create a mixin to provide the addText() like this. > > struct Exception > { > void addExceptionText( const std::string& str ) > { > // Add str to some private string. > } > > }; > > template<class T> > struct ExceptionTextMixin > { > T& addText( const std::string& str ) > { > // Use CRTP. > static_cast<T*>(this)->addExceptionText( str ); > return *static_cast<T*>(this); > } > > }; > > Now, for each ExceptionA, ExceptionB, ExceptionC, etc. > > struct ExceptionA : Exception, ExceptionTextMixin<ExceptionA> > { > > }; > > Is it ok to use mixins and CRTP for problems like this, or will I get in trouble later? > Seperate the message building from your exception class and things will be simpler. HTH -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Goran on 10 May 2010 04:37 On May 8, 7:21 pm, DeMarcus <use_my_alias_h...(a)hotmail.com> wrote: > Hi, > > I have a problem. I want to throw ExceptionA derived from Exception, > i.e. > > struct ExceptionA : Exception > { > > }; > > ExceptionA, ExceptionB, ExceptionC, etc. shall be able to attach text > to the exception directly at construction via function chaining, i.e. > > throw ExceptionA().addText( "Hello" ).addText( "World" ); > > The quick way to implement that would be the following. > > struct Exception > { > Exception& addText( const std::string& str ) > { > // Add str to some private string. > return *this; > } > > }; > > Now, the problem comes with the throw. > > throw ExceptionA().addText( "Hello" ).addText( "World" ); > > That will slice the exception and not throw an ExceptionA but instead > just a plain Exception since that is what addText() returns. > > My solution to this problem is written below, but before you scroll > down and get biased; how would you solve this? boost::exception does that already, and better, because it allows you to attach arbitrary info to exception object (you're only trying text). My guess is that http://www.boost.org/doc/libs/1_43_0/libs/exception/doc/tutorial_transporting_data.html is exactly what you're looking for. Goran. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Hakusa on 10 May 2010 04:37 On May 8, 1:21 pm, DeMarcus <use_my_alias_h...(a)hotmail.com> wrote: > Hi, > > I have a problem. I want to throw ExceptionA derived from Exception, i.e. > > struct ExceptionA : Exception > { > > }; > > ExceptionA, ExceptionB, ExceptionC, etc. shall be able to attach text to the exception directly at construction via function chaining, i.e. > > throw ExceptionA().addText( "Hello" ).addText( "World" ); > > The quick way to implement that would be the following. > > struct Exception > { > Exception& addText( const std::string& str ) > { > // Add str to some private string. > return *this; > } > > }; > > Now, the problem comes with the throw. > > throw ExceptionA().addText( "Hello" ).addText( "World" ); > > That will slice the exception and not throw an ExceptionA but instead just a plain Exception since that is what addText() returns. I do not entirely understand why this is necessary. If this addText function is proving difficult, why not do something more obvious? std::string exceptionText = "Hello "; exceptionText += "world"; throw ExceptionA( exceptionText ); // Make ctor accept string. Maybe this is overly simplistic. Maybe you want something to be done to the string, other than concatenation. In that case, write a function that concatenates the string with whatever extra you need! But, maybe ExceptionA().addText(string("x")+string("y")) will have a different effect than ExceptionA().addText("x").addText("y"). Then how about this: // Assuming that overloading this function per type is impractical. template< typename E > E addText( E e, string str ) { e.addText( str ); return e; } // Somewhere, later on... throw addText( addText(ExceptionA(), "Hello"), "World" ); Using C++0x, there are variadic templates and a variadic ctor would solve this whole problem, no? G++ currently supports this, but i don't believe MSVC does... yet. I think this problem should be defined more clearly. If addText does nothing but adds text, concatenation, then my first solution is adequate, just a little inconvenient for getting it all done in one line. If addText does anything more, then my last solution should be adequate. Though, ignoring all that, what's wrong with this: ExceptionA e; e.addText("x").addText("y"); throw e; Is part of the specification for the problem "Must be done in one line."? All this seems like a lot of work for just pretty syntax, unless i'm missing something. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Öö Tiib on 10 May 2010 04:37 On 8 mai, 20:21, DeMarcus <use_my_alias_h...(a)hotmail.com> wrote: > Hi, > > I have a problem. I want to throw ExceptionA derived from Exception, i.e. > > struct ExceptionA : Exception > { > > }; > > ExceptionA, ExceptionB, ExceptionC, etc. shall be able to attach text to the exception directly at construction via function chaining, i.e. > > throw ExceptionA().addText( "Hello" ).addText( "World" ); > > The quick way to implement that would be the following. > > struct Exception > { > Exception& addText( const std::string& str ) > { > // Add str to some private string. > return *this; > } > > }; > > Now, the problem comes with the throw. > > throw ExceptionA().addText( "Hello" ).addText( "World" ); > > That will slice the exception and not throw an ExceptionA but instead just a plain Exception since that is what addText() returns. > > My solution to this problem is written below, but before you scroll down and get biased; how would you solve this? I would perhaps use templated operator <<. It looks better when it is used in such places. struct Exception { void addText( const std::string& str ) { // Add str to some private string. } }; struct ExceptionA : Exception {}; template < class E > E& operator<<( E& x, std::string txt ) { x.addText( txt ); return x; } int main() { throw ExceptionA() << "Hello" << "World"; } -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Next
|
Last
Pages: 1 2 3 4 Prev: C++ Compiler Next: make_array - or auto deducing the number of elements to std::array |