Пример here для std::forward
,Как конструктор перемещения переменной-члена вызывается без использования std :: forward?
// forward example
#include <utility> // std::forward
#include <iostream> // std::cout
// function with lvalue and rvalue reference overloads:
void overloaded (const int& x) {std::cout << "[lvalue]";}
void overloaded (int&& x) {std::cout << "[rvalue]";}
// function template taking rvalue reference to deduced type:
template <class T> void fn (T&& x) {
overloaded (x); // always an lvalue
overloaded (std::forward<T>(x)); // rvalue if argument is rvalue
}
int main() {
int a;
std::cout << "calling fn with lvalue: ";
fn (a);
std::cout << '\n';
std::cout << "calling fn with rvalue: ";
fn (0);
std::cout << '\n';
return 0;
}
Output:
calling fn with lvalue: [lvalue][lvalue]
calling fn with rvalue: [lvalue][rvalue]
упоминает, что
тот факт, что все названные значения (такие как параметры функции) всегда оценить, как lvalues (даже тех, которые объявлены как ссылки RValue)
Принимая во внимание, что типичный конструктор перемещения выглядит как
ClassName(ClassName&& other)
: _data(other._data)
{
}
, который выглядит как _data(other._data)
, должен ссылаться на конструктор перемещения класса _data
. Но как это возможно без использования std::forward
? Другими словами, не должно быть
ClassName(ClassName&& other)
: _data(std::forward(other._data))
{
}
?
Потому что, как указано в станд: вперед случае,
все то названные значения должны оценить, как именующее
Я все больше и больше, как C++ из-за глубины вопроса, как это и тот факт, что язык достаточно смелый, чтобы обеспечить такие возможности :) Спасибо!
Вы должны использовать 'std :: move' в конструкторе. см.: [Как определить конструктор перемещения?] (http://stackoverflow.com/questions/9456910/howto-define-a-move-constructor) – NathanOliver
_ «В то время как типичный конструктор перемещения выглядит ...» _ Нет, нет. Кроме того, 'std :: forward' предназначен для _forwarding_ вещей как их исходной категории значений, либо rvalue, либо lvalue, в зависимости от аргумента шаблона, используемого с' std :: forward'. Просто сказать 'std :: forward (other._data)' без списка аргументов шаблона даже не будет компилироваться. Если вы просто хотите rvalue, используйте 'std :: move' не' std :: forward'. –
@JonathanWakely Но если аргумент lvalue ClassName (ClassName && other) даже не будет вызван, потому что прототип функции не сопоставляется. – user557583