Я пытаюсь понять, когда подходящее время использовать некоторые из структур, которые идут с 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
и «не значение»?
По сравнению с необработанным указателем дополнительная ссылка может указывать на то, что (1) арифметика указателя не используется, и (2) владение референтом сохраняется в другом месте (поэтому delete
явно не будет использоваться с переменной).
Отличный вопрос, и ответ Джона Цвинка выше верен. Однако некоторые люди (например, многие в комитете по стандартизации) сомневаются, достаточно ли этих причин для оправдания существования optional<T&>
, когда optional<T&>
может иметь такую запутанную семантику. Подумайте, что должно произойти, когда вы назначаете одного из этих парней. Должна ли она перенести ссылку (то есть сделать так, чтобы она указывала на другой объект), или присвоить через ссылку, как реальная T&
делает? Случай может быть сделан для любого, который вызвал бы беспорядок и тонкие ошибки. Поддержка для optional<T&>
был удален из предложение недавно принятый в C ++ 14.
Короче говоря, если вы хотите сделать свой код переносимым на C ++ 14 std::optional
предпочитаю T*
над boost::optional<T&>
,