jason.cipriani@gmail.com
12/3/2008 5:46:00 AM
On Dec 2, 11:00 pm, Salt_Peter <pj_h...@yahoo.com> wrote:
> On Dec 2, 8:57 pm, "jason.cipri...@gmail.com"
>
>
>
> <jason.cipri...@gmail.com> wrote:
> > I have an application with a class "AppException" derived from
> > std::exception. I have full control over the implementation of
> > "AppException". I have two constructors like this:
>
> > class AppException {
> > public:
> > ...
> > AppException (const char *msg, ...);
> > AppException (const std::exception &cause, const char *msg, ...);
> > ...
>
> > };
>
> > The first constructor takes a printf format string and optional
> > parameters. The second takes an std::exception as the root cause, and
> > the same printf-style message. This functionality is critical (I need
> > to be able to construct an AppException from just a message, or from a
> > message and an std::exception root cause), although this particular
> > interface is not critical.
>
> > My problem is that std::exception has a non-explicit const char *
> > constructor. Therefore it can be implicitly converted from a const
> > char *. So in cases where I am using the no-cause constructor but
> > where my format parameters are a single additional string, e.g.:
>
> > throw AppException("Some string: %s", someString);
>
> > The compiler (VS 2008's compiler) complains that both constructors are
> > possible matches (the second constructor also matches, it attempts to
> > implicitly convert the const char * to an std::exception, and pass
> > someString as "msg").
>
> > How can I get rid of this ambiguity, but still keep the same
> > functionality? I'm kind of frazzled and having trouble coming up with
> > ideas. If I could somehow say that I wanted std::exception(const char
> > *) to be explicit, that would be one way to solve the problem, but I
> > don't think that's possible.
>
> > Thanks,
> > Jason
>
> #include <iostream>
> #include <stdexcept>
>
> class AppException : public std::runtime_error
> {
> public:
> AppException(const char* s)
> : std::runtime_error(s) { }
> // other ctors
>
> };
>
> int main()
> {
> try
> {
> throw AppException("testing AppException");
> }
> catch( std::exception& r_e )
> {
> std::cout << "Error: ";
> std::cout << r_e.what() << std::endl;
> }
>
> }
>
> /*
> Error: testing AppException
> */
>
> std::runtime_error is itself a derivative of std::exception and has an
> explicit constructor. Consider std::logic_error, std::out_of_range,
> std::domain_error, etc as well should you plan to specialize your
> exceptions.
Thanks for the tip. This doesn't solve my problem, as I still want to
be able to use any std::exception as the "cause", not just a
runtime_exception. Still, I've modified it to derive from
runtime_exception anyways, as it definitely seems more appropriate.
Jason