исключение разыменования std :: unique_ptr не блокируется в блоке try-catch - PullRequest
0 голосов
/ 22 мая 2018

Допустим, у меня есть:

struct test {
    bool a;
    int b;
};

int main()
{
    std::unique_ptr<test> ptr;
    // don't init the ptr

    try
    {
        if (!ptr->a)
        {
            std::cout << "ok" << std::endl;
        }
    }
    catch (const std::exception &ex)
    {
        std::cout << "ex: " << ex.what() << std::endl;
    }

    return 1;
}

Итак, здесь я настраиваю уникальный указатель, но не инициализирую его (чтобы симулировать это в большей базе кода), но хочу перехватить исключение.

Проблема в том, что мое исключение не вызывается - я просто получаю сбой (ошибка доступа к памяти)

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

Так возможно ли перехватить исключение ссылки-уникального_птр?

РЕДАКТИРОВАТЬ: Я должен добавить, что этов Windows 7 работает исполняемый файл MSVS2012 - если это актуально!

1 Ответ

0 голосов
/ 22 мая 2018

Так можно ли поймать исключение разыменования уникальной_ptr?

Не существует исключения разыменования unique_ptr для перехвата.

Как документация гласит ,

Поведение не определено, если get() == nullptr

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

Для немного другой проблемы, описанной в комментариях:

У меня есть список unique_ptr - я пытался избежать индивидуальной проверки каждого из них, поместив вокруг него блок try.

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

if(any_of(begin(ptrs), end(ptrs), logical_not<unique_ptr<test>>{})
{
  throw MyNullPointerException();
}

В последующих комментариях вы можете просто добавить упаковку с проверкой и выбросом к своей функции конструирования.

В C ++ 17 вы можете почти получить то, что вывместо того, чтобы вернуть optional<unique_ptr<test>> (т. е.Она содержит заполненный unique_ptr или вообще ничего: в этом случае вызов value для извлечения unique_ptr приведет к выдаче std::bad_optional_access, если там его нет).

Если выможет импортировать ot (или не иметь C ++ 17), GSL , вероятно, даже лучше с gsl::not_null<T>.Например, вы можете вместо этого хранить эти вещи в своем контейнере

using unique_not_null = std::unique_ptr<gsl::not_null<test>>;
...