Используйте std :: необязательный как обычный указатель против использования has_value () и значения - PullRequest
0 голосов
/ 10 мая 2019

std::optional может использовать синтаксис для доступа к своему значению подобно обычному указателю, например.

std::optional<string> some_str;
if (some_str)
    (*some_str).c_str();

но он также имеет две функции, has_value() и value(), чтобы обеспечить доступ к его значению и проверить, существует ли значение.

std::optional<string> some_str;
if (some_str.has_value())
    some_str.value().c_str();

Мне интересно, чтоРазница между этими двумя Это для?
1. более многословный
2. производительность?
3. лучше ведение журнала и отладки?value() сгенерирует исключение.

Ответы [ 2 ]

5 голосов
/ 10 мая 2019

Здесь есть две разные вещи.

Сначала explicit operator bool() const против bool has_value() const. Это ровно синонимы . Они имеют в виду одно и то же. Используйте тот, который вы предпочитаете.

Второй, T& value() против T& operator*(). Это то же самое, что и vector :: at vs. vector :: operator [] . У первого нет предварительных условий - он проверяет и выбрасывает - у второго есть предварительные условия - это неопределенное поведение, если дополнительное отключено.

1 голос
/ 10 мая 2019

std::optional (без эксперимента, C ++ 17 на нас) определяет два различных интерфейса для доступа к его необязательному члену: проверенный доступ (std::optional::value) и незарегистрированный доступ (operator*).

Использование проверенного доступа имеет два потенциальных недостатка: во-первых, он замедляет выполнение, потому что выполняется ветвь, и, во-вторых, в случае отсутствия значения он вызывает исключение, что может быть нежелательно с точки зрения потока управления.В то время как вторая проблема может быть устранена посредством явной проверки наличия значения (std::optional::has_value) перед вызовом значения, затраты производительности во время выполнения все еще могут быть там.

У непроверенного доступа нет затрат на производительность, связанных сэто, но может быть безопасно использовано, только если вы знаете, что значение есть там каким-либо другим способом (то есть вы проверяли has_value ранее).В противном случае поведение программы не определено, и мы не хотим этого.

Из вышесказанного должно быть очевидно, что второй показанный вами фрагмент кода является чрезмерным:

if (some_str.hasvalue())
    some_str.value().c_str();

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

if (some_str.hasvalue())
    some_str->c_str();
...