повышение :: опционально & л; Т & амп; & GT; против Т *

Я пытаюсь понять, когда подходящее время использовать некоторые из структур, которые идут с 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 и «не значение»?

16

Решение

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

18

Другие решения

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

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

17