This is my generic exception and its base class, written in native C++:
class DRAException : public std::exception {
public:
DRAException( const std::string& what ) : std::exception( what.c_str() ) {}
virtual ~DRAException( ){}
};
template<typename T>
class InvalidArgumentException : public DRAException{
static std::string CreateErrorMessage( const std::string& argName, T value, boost::optional<T> min, boost::optional<T> max ){
std::string& errorMessage = "Invalid argument value for " + argName + ": " + StringUtils::toString(value);
if( min.is_initialized() )
errorMessage += ". Min value: " + StringUtils::toString( min.get() );
if( max.is_initialized() )
errorMessage += ". Max value: " + StringUtils::toString( max.get() );
return errorMessage;
}
public:
InvalidArgumentException( const std::string& argName, T value, boost::optional<T> min, boost::optional<T> max ) :
DRAException( CreateErrorMessage(argName, value, min, max) ){ }
};
In a C++/CLI assembly, I define a macro which maps native exceptions to managed ones:
#define BEGIN_EXCEPTION_GUARDED_BLOCK \
try {
#define END_EXCEPTION_GUARDED_BLOCK \
\
//Other catch clauses omitted for brevity's sake
} catch( DRAExceptions::InvalidArgumentException ex ) { \
throw gcnew System::ArgumentException( msclr::interop::marshal_as<System::String^>( ex.what() ) ); \
}
And then I use it like this:
void MCImage::FindOptimalLut( Single% fWindow, Single% fLevel ) {
BEGIN_EXCEPTION_GUARDED_BLOCK
pin_ptr<Single> pWindow = &fWindow, pLevel = &fLevel;
m_pNativeInstance->findOptimalLut( *pWindow, *pLevel );
END_EXCEPTION_GUARDED_BLOCK
}
But when trying to build the last piece of code, I get this error:
Image.cpp(72): error C2955: 'DRAExceptions::InvalidArgumentException' : use of class template requires template argument list
4> d:\svn.dra.workingcopy\mcommon\../CommonCppLibrary/CustomExceptions.h(50) : see declaration of 'DRAExceptions::InvalidArgumentException'
4>Image.cpp(72): error C2316: 'DRAExceptions::InvalidArgumentException' : cannot be caught as the destructor and/or copy constructor are inaccessible
I can’t specialize my templated class in the catch clause because that would defeat the purpose of catching all specializations regardless of type. As for the other error, both constructor and destructor are public, so I don’t get it. How can I work around this?
PS: I just started using the Boost libraries, so a Boost-specific solution is acceptable
You’re trying to use a type template as if it was a type. It isn’t – only instantiations of the template are types.
You can easily fix the problem in your case. Your class doesn’t need to be a template at all – only its constructor and the
CreateErrorMessagehelper function need to be templates.