Основные рекомендации по С++ были представлены недавно (поздравления!), и меня беспокоит тип gsl::not_null
. Как указано в I.12: Объявите указатель, который не должен быть нулевым как not_null
:
Чтобы избежать разыменования ошибок nullptr. Чтобы повысить производительность избегая избыточных проверок для nullptr.
...
Указывая намерение в источник, исполнители и инструменты могут обеспечить лучшую диагностику, такую как нахождение некоторых классов ошибок посредством статического анализа и выполнение оптимизации, такие как удаление ветвей и нулевые тесты.
Цель ясно. Однако у нас уже есть языковая функция. Указатели, которые не могут быть пустыми, называются ссылками. И хотя ссылки не могут восстанавливаться после их создания, эта проблема решается std::reference_wrapper
.
Основное различие между gsl::not_null
и std::reference_wrapper
я вижу в том, что последнее можно использовать только вместо указателей, в то время как первое работает ни на что nullptr
-assignable (цитата из F.17: Используйте not_null, чтобы указать, что значение "null" не является допустимым значением):
not_null
предназначен не только для встроенных указателей. Он работает дляarray_view
,string_view
,unique_ptr
,shared_ptr
и другие похожие на указатели типы.
Я представляю таблицу сравнения функций следующим образом:
T&
:
- Не удается сохранить
nullptr
? - Да - Rebindable? - Нет
- Может использоваться вместо чего-то, кроме указателей? - Нет
std::reference_wrapper<T>
:
- Не удается сохранить
nullptr
? - Да - Rebindable? - Да
- Может использоваться вместо чего-то, кроме указателей? - Нет
gsl::not_null<T*>
:
- Не удается сохранить
nullptr
? - Да - Rebindable? - Да
- Может использоваться вместо чего-то, кроме указателей? - Да
Теперь вот вопросы, наконец:
- Правильно ли я понимаю различия между этими понятиями?
- Означает ли это, что
std::reference_wrapper
теперь бесполезен?
PS Я создал теги cpp-core-guidelines
и guideline-support-library
для этого, надеюсь, правильно.