Основные рекомендации по С++ были представлены недавно (поздравления!), и меня беспокоит тип 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 для этого, надеюсь, правильно.