2013-06-09 4 views
16

Я пытаюсь понять, когда настало время использовать некоторые из структур, которые поставляются с boost, и у вас возникли вопросы относительно использования boost::optional со ссылкой.boost :: optional <T&> vs T *

Пусть у меня есть следующий класс, используя 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 и «не значением»?

+0

boost :: optional только обертка T *. Предпочитаю T *, чем boost :: optional из-за boost :: optional странно в C++. T * имеет лучшую читаемость – jean

ответ

18

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

+1

Хм, я думаю, это имеет смысл. Благодарю. – Lee

+7

В Modern C++ необработанный указатель должен уже предположить, что право собственности поддерживается в другом месте. –

17

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

Короче говоря, если вы хотите, чтобы ваш код переносился на C++ 14's std::optional, предпочитайте T* за boost::optional<T&>.

 Смежные вопросы

  • Нет связанных вопросов^_^