Re: Preventing implicit calling of non-explicit constructor.
 
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