Почему квалифицированное const rvalue std :: option :: value () возвращает ссылку на const rvalue?

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&&?

7

Решение

Конечно. У тебя есть 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&& контекст.

7

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]