std::optional::value()
имеет следующие две перегрузки
constexpr T& value() &;
constexpr const T & value() const &;
constexpr T&& value() &&;
constexpr const T&& value() const &&;
Какой смысл возвращать постоянную ссылку?
Единственная причина, по которой я могу придумать, — это позволить компилятору помогать ловить неопределенное поведение в (действительно очень странных) случаях, подобных следующему
auto r = std::cref(const_cast<const std::optional<int>&&>(
std::optional<int>{}).value());
Где если std::optional::value()
вернул const T&
тогда приведенный выше код скомпилируется и приведет к неопределенному поведению, когда r
reference_wrapper
был использован позже.
Имеется ли в виду какой-либо другой угловой случай, когда вышеизложенное возвращает const T&&
?
Конечно. У тебя есть const optional<T>
в структуре. Вы возвращаете экземпляр rvalue и получаете доступ к необязательному члену.
Из-за того, как вы его построили, вы можете гарантировать, что в этом случае задействуется дополнительный. Так вы звоните value()
, Тип T
содержит mutable
состояние, которое может быть эффективно повторно использовано / украдено. T const&&
Перегрузка дает функции-потребителю разрешение на кражу этого состояния.
struct mutable_type {
mutable std::vector<char> cache;
};
struct test_type {
const std::optional<mutable_type> bob;
};
test_type factory( int x ) {
if (x==0) return {};
return {mutable_type({{1,2,x}})};
}
auto moved_into = factory(3).bob.value().cache;
Это, я считаю, движет vector
в bob
, который является const
Значение в этом контексте. Опирается на value()
возвращая const&&
в const&&
контекст.
Других решений пока нет …