2013-09-05 4 views
3

Я очень озадачен std :: move stuff. Предположим, у меня есть этот кусок кода:Сколько раз вызываются конструкторы?

string foo() { 
    string t = "xxxx"; 
    return t; 
} 

string s = foo(); 

Сколько раз строка конструктор вызывается? Это 2 или 3? Используется ли компилятор для перемещения по этой строке?

string s = foo(); 

Если да, то в функции я даже не возвращающей ссылку RValue, так как может компилятор вызывать конструктор двигаться?

ответ

4

Это зависит от компилятора. В этом случае стандарт требует, чтобы был хотя бы один вызов конструктора. А именно, строительство t.

Но стандарт допускает возможность двух других: Move-строительство выходного значения foo из t, и вселения строительство s от выходного значения foo. Большинство достойных компиляторов откажутся от этих конструкторов, построив t непосредственно в памяти для s. Эта оптимизация становится возможной, поскольку стандарт позволяет этим конструкторам не вызываться, если компилятор не хочет этого делать.

Это называется копирование/перемещение «элиция».

Если это так, то в функции я даже не возвращаю ссылку rvalue, так как компилятор может вызвать конструктор перемещения?

Вы, кажется, трудясь в заблуждение, что && означает «движение», и что, если там нет && где-то, то движение не может произойти. Или для этого строительства требуется move, что также неверно.

C++ указан таким образом, что определенные типы выражений в определенных местах считаются действительными для перемещения. Это означает, что значение или ссылка попытаются привязать к параметру && перед привязкой к параметру &. Например, временные ряды будут предпочтительно связываться с параметром && до const&. Вот почему временные элементы, используемые для построения значений этого типа, будут перемещены.

Если у вас есть функция, которая возвращает значение некоторого типа T, и выражение возвращаемого имеет вид return x, где x является именованным переменным типа T автоматической продолжительности хранения (т.е. параметр функции или стек переменным), то стандарт требует, чтобы это возвращаемое выражение перемещало конструкцию возвращаемого значения от x.

Возвращаемое значение foo является временным. Правила C++ требуют, чтобы временные файлы связывались с параметрами && до const&. Таким образом, вы получаете конструкцию перемещения в s.

+0

Что делать, если мы предполагаем, что компилятор не делает никакой оптимизации? – WhatABeautifulWorld

+0

@WhatABeautifulWorld: Тогда это будет один конструктор, который, как я сказал, произойдет, плюс два дополнительных, которые, как я сказал, являются необязательными. –

+0

Мне нужно изменить определение функции для foo, чтобы его можно было переместить? Я думаю: string && foo() {...} В противном случае, как мог компилятор узнать? Строка - всего лишь пример, на самом деле у меня есть свой собственный объект ... – WhatABeautifulWorld

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