2013-07-06 1 views
13

Рассмотрят следующий пример, где мы разбираем данные и передать результат в следующую функцию:Как перейти от станда :: опциональной <T>

Content Parse(const std::string& data); 
void Process(Content content); 

int main() 
{ 
    auto data = ReadData(); 
    Process(Parse(data));  
} 

Теперь давайте изменим код, используя std::optional обрабатывать неудачный шаг разбора:

optional<Content> Parse(const std::string& data); 
void Process(Content content); 

int main() 
{ 
    auto data = ReadData(); 
    auto content = Parse(data); 
    if (content) 
     Process(move(*content)); 
} 

Действительно ли для переезда с optional<T>::value()? Если это нормально для std::optional, это действительно для boost::optional?

+0

Я бы подумал, что все будет хорошо. При переходе от него содержащееся значение должно находиться в правильном, но неуказанном состоянии. –

ответ

9

Действителен для перехода от optional<T>::value(), так как он возвращает изменяемую ссылку, и перемещение не уничтожает объект. Если случай optional не , занятый, value() исключает исключение bad_optional_access (§20.6.4.5).

Вы явно проверить, является ли занимается вариант:

if (content) 
    Process(move(*content)); 

Но вы не используете элемент value() для доступа к базовым T. Обратите внимание, что value() выполняет проверку внутри, прежде чем возвращать действительный T&, в отличие от operator*, который имеет предварительное условие 10, которое должно быть задействовано в качестве экземпляра optional. Это тонкое различие, но вы используете правильную идиому:

if (o) 
    f(*o) 

в отличие от

if (o) // redundant check 
    f(o.value()) 

В Boost, ситуация немного другая: во-первых, не существует никакой функции члена называется value(), что обеспечивает проверенный доступ. (A bad_optional_access исключения просто не существует). Член get() является просто псевдонимом для operator* и всегда полагается на пользователя, проверяющего, что задействован экземпляр optional.

+0

Есть ли у оператора '' ссылочная перегрузка rvalue? Т.е., 'f (* std :: move (o))' - это движется? Я надеюсь, что это так! – Yakk

+0

Я не смог найти его в [стандартном] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf). Взгляните на §20.6.4 на стр. 505, где описан интерфейс. – mavam

+1

Хм. 'value_or' имеет перегрузку' && 'и' & '. 'value' does not (Почему бы и нет? Наивно, он должен). Я мог видеть, что вы не хотите '' '' '' '' '' '' на случай, если люди соблазняются '*', не проверяя, включен ли «необязательный», но с метательным «значением» я не вижу вреда? – Yakk