#опытным
Мы разобрали, что перегрузки методов по ссылочным типам объектов могут быть полезными в разных контекстах. Они могут использовать как в совокупности для достижения универсальности в обработке объектов, или точечно для тонкой настройки-подкрутки функциональности
Но один из примеров в том посте выбивается из общей массы. Еще раз посмотрим на него:
template <typename T>
class optional {
// version of value for non-const lvalues
constexpr T& value() & {
if (has_value()) {
return this->m_value;
}
throw bad_optional_access();
}
// version of value for const lvalues
constexpr T const& value() const& {
if (has_value()) {
return this->m_value;
}
throw bad_optional_access();
}
// version of value for non-const rvalues... are you bored yet?
constexpr T&& value() && {
if (has_value()) {
return std::move(this->m_value);
}
throw bad_optional_access();
}
// you sure are by this point
constexpr T const&& value() const&& {
if (has_value()) {
return std::move(this->m_value);
}
throw bad_optional_access();
}
// ...
};
Это примерно то, как метод value класса std::variant был введен в стандарт С++17.
Мягко говоря, есть ощущение, что код дублируется. А если не считать мува, то вообще квадруплицируется.
Это вот стандартная штука, когда функции отличаются немного и их нельзя объединить в одну.
В таких случаях обычно помогают шаблоны. А учитывая, что у нас для левых ссылок нет мува, а для правых - есть, очень сильно напрашиваются универсальные ссылки и шаблонный std::forward.
Но тут шаблон вообще никак не вписывается. Методы же не принимают даже никаких аргументов. Какой шаблонный параметр сюда вообще вписывается?
Ну вообще говоря, методы принимают неявный аргумент this....
To be continued.
Intrigue people. Stay cool.
#cppcore