Связывание модифицируемой ссылки rvalue к модифицируемому lvalue - PullRequest
1 голос
/ 27 августа 2011

У меня 3 вопроса:

  1. Могу ли я связать lvalue напрямую со ссылкой на rvalue?

  2. Что происходит с объектом, который является std::move()?

  3. В чем разница между std :: move и std::forward?

struct myStr{
    int m_i;
};

void foo(myStr&& rs) { }

myStr rValueGene()
{
    return myStr();
}

int main() 
{
    myStr mS= {1};
    foo(rValueGene()); //ok passing in modifiable rvalue to rvalue reference

    // To Question 1:
    //below initilize rvalue reference with modifiable lvalue, should be ok
    //but VS2010 gives a compile error: error C2440: 'initializing' : cannot convert from    'myStr' to 'myStr &&' 
    //Is this correct ?
    myStr&& rvalueRef = mS;

    //by using std::move it seems ok, is this the standard way of doing this 
    //to pass a lvalue to rvalue reference
    //myStr&& rvalueRef = std::move(mS);

    // To Question 2:    
    //also what happens to mS object after std::move ?
    //destroyed , undefined ?
}

Ответы [ 2 ]

3 голосов
/ 27 августа 2011

1> Могу ли я связать lvalue напрямую со ссылкой на rvalue?

Не без явного приведения (например: std::move).

2> Что происходит с объектом, который является std :: move ()?

Ничего, пока он на самом деле не перемещен.Все, что std::move делает - возвращает ссылку на r-значение того, что вы ему дали.Фактическое перемещение происходит в конструкторе перемещения / назначении рассматриваемого типа.

3> В чем разница между std :: move и std :: forward?

std::move для перемещения;std::forward для пересылки.Это звучит беспечно, но это идея.Если вы собираетесь перемещать объект, используйте std::move.Если вы намерены переадресовать объект, вы используете std::forward.

Пересылка использует специализированную семантику, которая разрешает преобразования между типами ссылок, так что природа ссылок сохраняется между вызовами.Специфика всего этого очень ... техническая.

std::move всегда возвращает &&.Если вы дадите ему ссылку на l-значение, она вернет ссылку на r-значение.Если вы зададите ему тип значения, он вернет ссылку на это значение.И т. Д.

std::forward не не всегда возвращает &&.Синтаксически, std::forward просто делает static_cast<T&&>.Однако из-за специального синтаксиса приведения к типам && это приведение не всегда возвращает &&.Да, это странно, но это решает проблему пересылки, поэтому никому нет до этого дела.Вот почему он содержится в std::forward, вместо того, чтобы явно делать static_cast самостоятельно.

1 голос
/ 27 августа 2011

Вопрос 1. Да, компилятор верный.

Вопрос 2. Ничего не происходит. std::move просто приводит вещи к значениям.

Если, однако, вы должны использовать std::move для передачи mS (или myStr) в foo, то эта функция может предполагать, что она может «украсть» объект, и, таким образом, mS может оказаться в неопределенное состояние после вызова функции.

...