Предположим, что у меня есть класс Option
:Избегайте возвращения по ссылке аргумент
template<typename T>
class Option {
public:
Option() noexcept
{}
Option(T val) noexcept : val_(std::make_shared<T>(std::move(val)))
{}
const T & get() const
{
if (val_ == nullptr) {
throw std::out_of_range("get on empty Option");
}
return *val_;
}
const T & getOrElse(const T &x) const
{
return val_ == nullptr ? x : *val_;
}
private:
std::shared_ptr<T> val_;
};
Аргумент, передаваемый Option::getOrElse
это значение по умолчанию, чтобы вернуться, когда этот Option
пуст:
Option<int> x; // empty
int y = 123;
x.getOrElse(y); // == 123
Однако я что следующий код не является безопасным:
Option<int> x;
x.getOrElse(123); // reference to temporary variable!
Более безопасным способом было бы вернуть значение от Option::getOrElse
, но это было бы расточительно, если Option
не пуст. Могу ли я как-то обойти это?
UPDATE: Я думаю о том, возможно, перегрузках по типу аргумента (именующий/RValue) из getOrElse
, но еще не выяснил, как именно это сделать.
ОБНОВЛЕНИЕ 2: Возможно это?
T getOrElse(T &&x) const { ... }
const T & getOrElse(const T &x) const { ... }
Но я думаю, что это может быть неоднозначно, потому что аргументы lvalue и rvalue соответствуют второй версии.
Почему вы ничего не возвращаете? Если это проверка успеха или неудачи, вы можете вернуть «bool». – NathanOliver
@NathanOliver Я не уверен, что вы имеете в виду ...? 'getOrElse' - это getter со значением по умолчанию. –
Я не вижу значения по умолчанию в вашем коде. Вы пытаетесь объединить геттер и сеттер в одну функцию? – NathanOliver