Подтвердить что ты не робот

Boost:: optional <T &> vs T *

Я пытаюсь понять, когда подходящее время для использования некоторых структур, которые поставляются с boost, и возник вопрос о использовании boost::optional со ссылкой.

Предположим, что у меня есть следующий класс, используя boost::optional:

class MyClass {
public:
   MyClass() {}

   initialise(Helper& helper) {
      this->helper = helper;
   }

   boost::optional<Helper&> getHelper() {
      return helper;
   }

private:
   boost::optional<Helper&> helper;
}

Почему я должен использовать выше, а не:

class MyClass {
public:
   MyClass() : helper(nullptr) {}

   initialise(Helper& helper) {
      this->helper = &helper;
   }

   Helper* getHelper() {
      return helper;
   }

private:
   Helper* helper;
}

Они оба передают одно и то же намерение, т.е. что getHelper может возвращать null, и вызывающему все еще нужно проверить, был ли возвращен помощник.

Если вы используете только boost::optional, если вам нужно знать разницу между "значением", nullptr и "не значением"?

4b9b3361

Ответ 1

По сравнению с необработанным указателем необязательная ссылка может предполагать, что (1) арифметика указателя не используется, и (2) право собственности на референт поддерживается в другом месте (поэтому delete явно не будет использоваться с переменной).

Ответ 2

Отличный вопрос, и ответ Джона Звинка выше прав. Однако некоторые люди (например, многие из комитета по стандартизации) сомневаются, достаточно ли этих причин, чтобы оправдать существование optional<T&>, когда optional<T&> может иметь такую ​​запутанную семантику. Подумайте, что должно произойти, когда вы назначаете одного из этих ребят. Должен ли он повторно установить ссылку (т.е. Указывать на другой объект) или назначить через ссылку, как это делает реальный T&? Случай может быть сделан для обоих, что может вызвать путаницу и тонкие ошибки. Поддержка optional<T&> была удалена из предложения , которое недавно было принято на С++ 14.

Короче говоря, если вы хотите сделать свой код переносимым на С++ 14 std::optional, предпочитайте T* over boost::optional<T&>.