Ошибка компилятора при отлове шаблонного исключения - PullRequest
0 голосов
/ 02 января 2012

Это мое общее исключение и его базовый класс, написанный на родном 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) ){ }
};

В сборке C ++ / CLI я определяю макрос, который отображает собственные исключения в управляемые:

#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() ) ); \
    }

А потом я использую это так:

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
}

Но при попытке построить последний кусок кода я получаю эту ошибку:

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

Я не могу специализировать свой шаблонный класс в предложении catch, потому что это лишило бы цели отлов всех специализаций независимо от типа. Что касается другой ошибки, то и конструктор, и деструктор являются публичными, поэтому я не понимаю. Как я могу обойти это?

PS: я только начал использовать библиотеки Boost, так что подходящее для Boost решение приемлемо

Ответы [ 2 ]

3 голосов
/ 02 января 2012

Вы пытаетесь использовать шаблон типа, как если бы он был типом. Это не так - только экземпляры шаблона являются типами.

Вы можете легко решить проблему в вашем случае. Ваш класс вообще не должен быть шаблоном - только его конструктор и вспомогательная функция CreateErrorMessage должны быть шаблонами.

3 голосов
/ 02 января 2012

Компилятор точно скажет, в чем проблема:

использование шаблона класса требует списка аргументов шаблона

Вы не можете поймать все возможные исключения в одном улове. У вас должен быть один для каждого отдельного улова T, или со ссылкой на общий базовый класс.

catch (const DRAException& Ex)
...