Когда нам практически нужны "явные значения x"?
Определение xvalue выглядит следующим образом:
- значение xvalue (значение "eXpiring" ) также относится к объекту, обычно ближе к концу его жизненного цикла (так что его ресурсы могут быть перемещены, например). Значение x является результатом определенных видов выражений, содержащих ссылки rvalue (8.3.2). [Пример: результат вызова функции, тип возврата которой является ссылкой rvalue, является значением x. -end пример]
Будем ли мы когда-либо попадать туда, где нам практически нужно использовать функцию, тип возврата которой является ссылкой rvalue, которая является значением x?
const int && Foo()
{
// ...
}
Перемещение семантики принимает значение rvalue как параметр, а не возвращаемое значение. Поэтому я не думаю, что дело.
Ответы
Ответ 1
Возвращаемые ссылки rvalue могут быть полезны для функций, которые уже принимают значения rvalues в качестве параметров. Простой пример:
struct X {
X() = default;
X(X&& other) { std::cout << "move ctor\n"; }
X(X const&) = delete;
void log(std::string const& s){ std::cout << "log: " << s << "\n"; }
};
void sink(X&& x) {
x.log("sink");
}
X&& passOn(X&& in) {
in.log("pass");
return std::move(in);
}
X moveOn(X&& in) {
in.log("move");
return std::move(in);
}
int main() {
sink(passOn(X()));
std::cout << "===============================\n";
sink(moveOn(X()));
}
Живая демонстрация →
Вторая функция вызовет конструктор перемещения для создания возвращаемого объекта, в то время как первый передаст ссылку, которую он уже получил. Это более полезно, если мы не возвращаем исходную ссылку, а вместо этого ссылаемся на часть упомянутого объекта, например
template<class T>
T&& getHead(std::vector<T>&& input) {
return std::move(input.front());
}
Ответ 2
Именно это std:: move - результат выполнения std::move
- это значение xvalue. Кроме того, это трудно сказать, так как в основном возвращение ссылки из функции плохое время от времени. Но, возможно, кто-то придумает другое умное использование такой функции.
Ответ 3
Будем ли мы когда-либо попадать туда, где нам практически нужно использовать функцию, тип возврата которой является ссылкой rvalue, которая является значением x?
Он используется в классах контейнеров, например tuple
имеет перегрузку get
, которая выглядит следующим образом:
template< std::size_t I, class... Types >
typename std::tuple_element<I, tuple<Types...> >::type&&
get( tuple<Types...>&& t );
Я предполагаю, что std::optional
и std::variant
в С++ 17 будут иметь одинаковые перегрузки.
Конечно, единственное, что следует избегать, чтобы ввести std::move
в некоторых очень конкретных ситуациях, например:
auto x = std::get<1>( f() );
Где f
возвращает кортеж по значению.