2015-11-10 2 views
0

Как переместить семантику работы в этом примере:Когда перемещение семантики работает с std :: move?

struct test { 
    int ii[10]; 
    int i; 
}; 

test f() { 
    test a; 
    std::cout << "[1] " << &a << std::endl; 
    return a; 
} 

int main() 
{ 
    test x (f()); 
    std::cout << "[2] " << &x << std::endl; 
    test x1 (std::move(x)); 
    std::cout << "[3] " << &x1; 
} 

Выход:

[1] 0x7fff50ac70c0 
[2] 0x7fff50ac70c0 
[3] 0x7fff50ac70f0 

Почему х была построена с использованием возвращаемого значения F(), но x1 получил другой адрес, чем х?

Редактировать

struct test { 
    std::string s; 
} 

[...] 

std::cout << (*void)&x.s[0]; 

Я думаю, что я понял, в конце концов. Теперь адреса совпадают.

+6

Потому что вы неверно истолковываете, что означает «движение» в C++ 11. Когда вы двигаетесь (в смысле перемещения), ваш адрес тоже меняется. Но вы перемещаете свою мебель и все свои вещи. Это в основном то, что означает «перемещение» в C++ 11. Адрес меняется. Это другой объект, чем тот, с которого вы «переходите». Но «внутренности» перемещаются из А в Б. И, кстати, 'std :: move' не перемещается. Это делает объект «подвижным», т. Е. Вы говорите своему компилятору «Мне больше не нужно' x'. Вам не нужно копировать его внутренние элементы в 'x1', вы можете их перемещать». – leemes

+1

В дополнение к комментарию @leemes, взгляните на NRTO (Именованная оптимизация возвращаемого значения). – OMGtechy

ответ

5

Это не имеет ничего общего с семантикой перемещения. a и x имеют одинаковый адрес памяти, так как копия elided, поэтому возврат f выделяется непосредственно на сайте вызова. x1 не имеет того же адреса, что и x, потому что это отдельный объект, а отдельные объекты не могут иметь один и тот же адрес. Перемещение не изменяет адрес, это позволяет вырезать кишки вашего объекта и sellotaped в перемещенный объект.