dynamic_cast не генерирует исключения, как ожидалось

На основании этого ответа...

Поиск типа объекта в C++

... Я написал этот код:

        static TVALUE getUpperBound()
        {
            SomeStruct<TVALUE>* t;

            try
            {
                dynamic_cast<SomeStruct<bool>*> (t);
                return 1;
            }
            catch (int e)
            {
            }

            try
            {
                dynamic_cast<SomeStruct<unsigned char>*> (t);
                return 255;
            }
            catch (int e)
            {
            }

            try
            {
                dynamic_cast<SomeStruct<unsigned int>*> (t);
                return 65535;
            }
            catch (int e)
            {
            }

            return 0;
        }

Но не работает :-/

Я знаю, что есть ДРУГИЕ способы сделать это (используя включения), но мне нужно, чтобы этот метод работал.

Я не могу включать какие-либо включения в свой код (это длинная история, но я просто не могу)... отсюда и эта попытка сделать что-то, что можно было бы легко сделать с помощью climits или typeinfo.

Может ли кто-нибудь объяснить мне, почему это не работает?

Редактировать 1:

Спасибо, парни. Я пропустил бит ссылки и указателя.

Это работает сейчас:

template <typename TVALUE>
TVALUE getUpperBound()
{
    SomeStruct<TVALUE>* t;

    if (dynamic_cast<SomeStruct<bool>*> (t) != nullptr)
        return 1;
    if (dynamic_cast<SomeStruct<unsigned char>*> (t) != nullptr)
        return 255;
    if (dynamic_cast<SomeStruct<unsigned int>*> (t) != nullptr)
        return 65535;

    return 0;
}

Редактировать 2:

Я попробовал совет @StilesCrisis и использовал специализацию шаблона.

template <typename TVALUE>
TVALUE getUpperBound();

template <>
bool getUpperBound<bool>()
{
    return 1;
}

template <>
unsigned char getUpperBound<unsigned char>()
{
    return 255;
}

template <>
unsigned int getUpperBound<unsigned int>()
{
    return 65535;
}

Работает очарование. Гораздо лучшая реализация. Спасибо!


person Beakie    schedule 20.09.2014    source источник
comment
Это вызовет исключение, когда вы будете использовать приведение к ссылочному типу, но вы используете указатели. Внимательно читайте документацию   -  person grisha    schedule 20.09.2014
comment
@ user2451677: Почему вы пишете ответы в виде комментариев?   -  person Lightness Races in Orbit    schedule 20.09.2014
comment
У меня нет времени, чтобы написать более подробный ответ   -  person grisha    schedule 20.09.2014
comment
Ваш пример кода был бы лучше в качестве специализации шаблона. Гораздо дешевле и столь же выразительно.   -  person StilesCrisis    schedule 20.09.2014
comment
Не могли бы вы объяснить?   -  person Beakie    schedule 20.09.2014
comment
Теперь пришло время узнать о numeric_limits. :)   -  person StilesCrisis    schedule 21.09.2014
comment
:) Я не могу использовать файлы заголовков (правда) ... иначе я бы это сделал. Если вы напишете как ответ, я буду рад отметить его как таковой.   -  person Beakie    schedule 21.09.2014


Ответы (2)


Вы выполняете кастинг к указателю. bad_cast генерируется только при приведении к ссылке.

Вы можете просто проверить наличие nullptr, если приведение к ссылке нежелательно.

person StilesCrisis    schedule 20.09.2014

dynamic_cast генерирует исключения только в случае сбоя, если его аргумент шаблона является ссылочным типом.
Когда это тип указателя, dynamic_cast вместо этого оценивается как NULL в случае сбоя.

Это очень ясно показано в справке по предпочтительному языку, для которого вы могли бы просто Погуглил:

5c) В противном случае проверка во время выполнения завершается неудачно. Если dynamic_cast используется для указателей, возвращается нулевое значение указателя типа _new_type_. Если он использовался для ссылок, выдается исключение std::bad_cast.

Я также не понимаю, почему вы ожидаете, что будет выброшено int, а не что-то, что выводит std::exception. Возможно, вы надеялись, что return в блоке try перейдет к соответствующему блоку catch? Это не так.

person Lightness Races in Orbit    schedule 20.09.2014
comment
dynamic_cast не является шаблоном. Похоже на шаблон - person grisha; 20.09.2014
comment
Это шаблон. Извините, что не сделал это яснее. - person Beakie; 20.09.2014