Когда мы можем использовать юниформ-инициализацию, чтобы легко создать по умолчанию std::optional<T>
?
std::optional<T> foo() {
if (on_error)
return {};
// ...
}
Есть ли недостаток в вышеизложенном, который решает std::nullopt
?
Когда мы можем использовать юниформ-инициализацию, чтобы легко создать по умолчанию std::optional<T>
?
std::optional<T> foo() {
if (on_error)
return {};
// ...
}
Есть ли недостаток в вышеизложенном, который решает std::nullopt
?
Нет
Это вполне допустимый способ построения по умолчанию optional
.
Даже для назначения вы можете скопировать-назначить построенный по умолчанию optional
с = {}
вместо использования std::nullopt
:
cppreference на самом деле говорит об этом:
Существуют ограничения на конструкторы
nullopt_t
для поддержки какop = {};
, так иop = nullopt;
в качестве синтаксиса для отключения необязательного объекта.
… как и исходное предложение по функция:
Обратите внимание, что это не единственный способ отключить необязательный объект. Вы также можете использовать:
op = std::nullopt;
Вы можете спросить себя, почему тогда std::nullopt
вообще существует. В предложении это тоже рассматривается< /а>:
это вводит избыточность в интерфейс
[похожий пример]
С другой стороны, есть случаи, когда использование nullopt нельзя заменить никаким другим удобным обозначением:
void run(complex<double> v); void run(optional<string> v); run(nullopt); // pick the second overload run({}); // ambiguous if (opt1 == nullopt) ... // fine if (opt2 == {}) ... // illegal bool is_engaged( optional<int> o) { return bool(o); // ok, but unclear return o != nullopt; // familiar }
Хотя в некоторых ситуациях синтаксис {} будет работать, использование nullopt делает намерение программиста более ясным. Сравните это:
optional<vector<int>> get1() { return {}; } optional<vector<int>> get2() { return nullopt; } optional<vector<int>> get3() { return optional<vector<int>>{}; }
Короче говоря, std::nullopt
может быть полезен, но в вашем случае это просто сводится к стилю.
Есть ли какой-либо недостаток в вышеизложенном, который решает
std::nullopt
?
Да.
В некоторых контекстах вы можете захотеть условно вернуть отключенный необязательный объект (пустой, если хотите), а синтаксис инициализации {}
нельзя однозначно использовать для вывода типа std::nullopt_t
. Например, как описано в разделе Возврат необязательного значения с помощью оператора ?:, при возврате пустого или непустого параметра через выражение тернарного оператора:
return it != map.end() ? std::make_optional(it->second) : std::nullopt;
auto
?
- person Sebastian Hoffmann; 16.07.2020
true
соответствует типу возвращаемого значения. Но, тем не менее, выражение {}
здесь недопустимо.
- person Asteroids With Wings; 16.07.2020