Когда я запускаю следующую программу, я получаю искаженное имя typeinfo.
#include <iostream>
#include <stdexcept>
#include <typeinfo>
namespace std
{
class really_out_of_range
: public out_of_range
{
public:
explicit really_out_of_range(const string& __s) : out_of_range(__s) {}
explicit really_out_of_range(const char* __s) : out_of_range(__s) {}
virtual ~really_out_of_range() _NOEXCEPT {}
};
}
void test () noexcept(false)
{
throw std::really_out_of_range("x > 20");
}
int main () noexcept(true)
{
try {
test();
} catch (const std::exception& e) {
std::cout << "Exception caught: " << typeid(e).name() << ": " << e.what() << '\n';
} catch (...) {
std::cout << "Unknown exception caught\n";
}
}
Вот результат:
Обнаружено исключение: St19really_out_of_range: x> 20
Однако, когда я меняю спецификацию noexcept в функции test()
на true
, чтобы вызвать вызов std::terminate()
, я получаю следующий результат:
libc ++ abi.dylib: завершение с неперехваченным исключением типа std :: really_out_of_range: x> 20
Я думал, что std :: terminate () может предоставить названный немангулированный тип, потому что он явно обрабатывает каждый стандартный тип исключения, но это явно не так, потому что он также правильно обрабатывает новый тип исключения, который я определил выше.
Итак, мой вопрос: почему имя typeinfo правильное в std::terminate()
, а не тогда, когда я пытаюсь получить к нему доступ напрямую? Или, что более важно, какую функцию вызывает std::terminate()
, которая предоставляет несвязанное имя класса?
std::terminate
просто разоблачает имя typeinfo. Вероятно, он использует внутреннюю функцию среды. Например, в G ++ естьabi::__cxa_demangle
. - person cdhowie   schedule 17.04.2017typeid(anything).name()
определяется реализацией.std::terminate()
не требуется для распознавания (или представления типа исключения в какой-либо конкретной форме), и нет стандартной функции для распознавания имени. Наконец, добавление объявлений в пространство именstd
, как у вас, дает неопределенное поведение. - person Peter   schedule 17.04.2017