2013-10-01 3 views
6

Я пытаюсь понять ссылку rvalue и перенести семантику. В следующем коде, когда я передаю 10 в функцию Print, он вызывает переназначение ссылочной стоимости rvalue, что ожидается. Но что именно происходит, где будет скопировано 10 (или откуда оно указано). Во-вторых, что делает std::move на самом деле? Извлекает ли значение 10 из i, а затем передает его? Или это инструкция для компилятора использовать ссылку rvalue?Что именно происходит, когда мы используем ссылки rvalue и как работает std :: move?

void Print(int& i) 
{ 
    cout<<"L Value reference "<<endl; 
} 

void Print(int&& i) 
{ 
    cout<<"R Value reference "<< endl; 
} 

int main() 
{ 
    int i = 10; 

    Print(i); //OK, understandable 
    Print(10); //will 10 is not getting copied? So where it will stored 

    Print(std::move(i)); //what does move exactly do 

    return 0; 
} 

Спасибо.

+2

Рекомендую посмотреть [Scott Meyers talk on Going Native 2013] (http://channel9.msdn.com/Events/GoingNative/2013/An-Effective-Cpp11-14-Sampler). Он подробно объясняет 'std :: move' и' std :: forward'. – danadam

ответ

8

Но что именно происходит, когда что 10 будет скопирована (или откуда она называется)

Временная ценность создается, а ссылка передается функции. Временами являются rvalues ​​, поэтому могут быть связаны с rvalue ссылки; поэтому выбирается вторая перегрузка.

Во-вторых, что std::move на самом деле делаете?

Это дает вам rvalue ссылка на его аргумент. Он эквивалентен (по определению) до static_cast<T&&>.

Несмотря на название, оно не производит никакого движения; он просто дает вам ссылку, которая может использоваться для перемещения значения.

-1

std::move литье int в int&& через static_cast<int&&>. В конце концов, если тип является class или struct, вместо него будет вызываться конструктор перемещения, если он определен (неявно или явно), вместо /classical constructor.

+1

ОК, у меня есть половина ответа на мой вопрос .., потому что я до сих пор не понимаю, что произойдет, если я передам значение как rvalue ref –

9

В случае 10, вероятно, будет оптимизаций, участвующих которые изменят фактическую реализацию, но концептуально, происходит следующее:

  • Временный int создается и инициализируется со значением 10.

  • что временные int связан с параметром функции опорного г-значение.

Таким образом, концептуально нет копирования - ссылка будет ссылаться на временную.

Что касается std::move(): могут быть некоторые сложные биты, связанные со ссылками и т. Д., Но в основном это просто ссылка на r-значение. std::move()не фактически переезд ничего. Он просто превращает свой аргумент в значение r, чтобы его можно было перемещать.

«Перемещение» на самом деле не является определенной операцией. В то время как удобно думать о переезде, важно отметить значение l-value и r-value.

«Перемещение», как правило, реализуется конструкторами перемещения, переводит операторы присваивания и функции, содержащие ссылки на r-значение (например, push_back()). Именно их реализация делает движение реальным движением - то есть они реализованы так, что они могут «украсть» ресурсы r-значения вместо их копирования. Это потому, что, будучи r-значением, он больше не будет доступен (или вы обещаете компилятор).

Именно поэтому std::move() позволяет «перемещаться» - он превращает свой аргумент в значение r, сигнализирует «эй, компилятор, я больше не буду использовать это значение l, вы можете позволить функции (такие как перемещение ctors) рассматривают его как r-значение и украдут у него ».

+1

Эта временная переменная означает безымянный объект? –

+0

@pranitkothari Я никогда не говорил временную переменную *. Это будет временный * объект * типа 'int'. Да, это будет безымянный. – Angew

Смежные вопросы