Я думаю, нет, но я хотел бы подтвердить. Используется ли для const Foo&&
, где Foo
- тип класса?
Нужны ли ссылки rvalue на const?
Ответ 1
Они иногда полезны. Сам проект С++ 0x использует их в нескольких местах, например:
template <class T> void ref(const T&&) = delete;
template <class T> void cref(const T&&) = delete;
Вышеуказанные две перегрузки гарантируют, что другие функции ref(T&)
и cref(const T&)
не свяжутся с rvalues (что в противном случае было бы возможно).
Обновление
Я только что проверил официальный стандарт N3290, который, к сожалению, не является общедоступным, и имеет в 20.8 функциональных объектов [ function.objects]/p2:
template <class T> void ref(const T&&) = delete;
template <class T> void cref(const T&&) = delete;
Затем я проверил самый последний проект пост-С++ 11, который является общедоступным, N3485, а в 20.8 Объекты функции [function.objects]/p2 он все еще говорит:
template <class T> void ref(const T&&) = delete;
template <class T> void cref(const T&&) = delete;
Ответ 2
Они разрешены и даже функции ранжируются на основе const
, но поскольку вы не можете перемещаться из объекта const, указанного const Foo&&
, они не являются полезными.
Ответ 3
Я не могу думать о ситуации, когда это было бы полезно непосредственно, но оно может использоваться косвенно:
template<class T>
void f(T const &x) {
cout << "lvalue";
}
template<class T>
void f(T &&x) {
cout << "rvalue";
}
template<class T>
void g(T &x) {
f(T());
}
template<class T>
void h(T const &x) {
g(x);
}
T в g является T const, поэтому f x является T const & &.
Вероятно, это приводит к ошибке компиляции в f (когда она пытается переместить или использовать объект), но f может принять rvalue-ref, чтобы его нельзя было вызывать на lvalues, не изменяя значение rvalue (как в слишком простой пример выше).
Ответ 4
Помимо std :: ref, стандартная библиотека также использует ссылку на константное значение в std :: as_const для той же цели.
template <class T>
void as_const(const T&&) = delete;
Он также используется как возвращаемое значение в std :: необязательный при получении обернутого значения:
constexpr const T&& operator*() const&&;
constexpr const T&& value() const &&;
Как и в std :: get:
template <class T, class... Types>
constexpr const T&& get(const std::variant<Types...>&& v);
template< class T, class... Types >
constexpr const T&& get(const tuple<Types...>&& t) noexcept;
Предположительно это делается для того, чтобы поддерживать категорию значения, а также постоянство оболочки при доступе к перенесенному значению.
Это делает различие в том, можно ли вызывать постоянные ref-квалифицированные функции для обернутого объекта. Тем не менее, я не знаю использования для conts rvalue ref квалифицированных функций.