2009-05-09 2 views
20

Одной из замечательных новых функций предстоящего стандарта C++, C++ 0x, являются «ссылки rvalue». Ссылка Rvalue похож на Lvalue (нормальной) ссылки, за исключением того, что оно может быть связано с временным значением (обычно, временно может быть связан только с const ссылкой):Почему ссылка на C++ 0x rvalue не по умолчанию?

void FunctionWithLValueRef(int& a) {...} 
void FunctionWithRValueRef(int&& a) {...} 

int main() { 
    FunctionWithLValueRef(5); // error, 5 is a temporary 
    FunctionWithRValueRef(5); // okay 
} 

Итак, почему же они изобретать совершенно новый тип, вместо того, чтобы просто удалять ограничения на нормальные ссылки, чтобы они могли привязываться к временным?

+3

Интересно, почему это получило 3 голоса, но 7 фаворитов. Я не думаю, что когда-либо высказывал вопрос, не проголосовав за него (если я не был вне голоса или был заблокирован). – Zifre

+3

Интересно, почему кто-то что-то думает, и тогда он ожидает, что все остальные будут делать то, что он делает. – user534498

+1

Интересно, почему «быть красивым и дарить верх» является необоснованным ожиданием. –

ответ

43

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

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

string toupper(string && s) { // for nonconst rvalues 
    for(char &c : s) make_uppercase(c); 
    return move(s); // move s into a returned string object 
} 

string toupper(string const& s) { // for the rest 
    // calls the rvalue reference version, by passing 
    // an rvalue copy. 
    return toupper(string(s)); 
} 

Теперь, если у вас есть RValue и передать его TOUPPER, то Rvalue может напрямую быть изменен, потому что мы знаем, что временно это выбрасывать вещь в любом случае, так что мы можем Aswell просто изменить его и Дон» нужно скопировать его. Кроме того, одно и то же наблюдение используется для объекта, называемого move-constructors и move-assign. Правая сторона не копируется, но ее вещи просто украдены и перемещены в *this.

Если бы вы сказали, что rvalues ​​могут связываться с не-константными ссылками lvalue, то вы не сможете определить, ссылается ли это на значение lvalue (named object) или rvalue (временное) в конце.


Это, вероятно, более мало знают, но полезно в любом случае, вы можете положить Lvalue или RValue реф-отборочные на функцию члена. Вот пример, который естественным образом расширяет существующую семантику RValue ссылок на неявный параметр объекта:

struct string { 
    string& operator=(string const& other) & { /* ... */ } 
}; 

Теперь вы не можете больше сказать

string() = "hello"; 

Что сбивает с толком и на самом деле не делаете смысл в большинстве случаев. То, что делает &, говорит о том, что оператор присваивания может быть вызван только на lvalues. То же самое можно сделать для rvalues, положив &&.

+1

+1 Wow спасибо за последнюю часть о lvalues ​​/ rvalues ​​только звоните!Я много читал о C++ 0x, но ничего не видел об этом (думаю, это в последнем черновике, но я его не читал). Можете ли вы указать мне некоторую документацию об этой функции? – Klaim

+0

Вот хороший обзор: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1821.htm. В рабочем документе см. 8.3.5, 9.3.1 и 13.3.1. –

+0

Спасибо за этот ответ, это делает его намного яснее. Я просто не очень хорошо понимал ссылки на rvalue. Это имеет гораздо больше смысла, чем то, о чем я думал. – Zifre

12

Поскольку добавление нового типа ссылки позволяет записать два перегруженных метода:

void CopyFrom(MyClass &&c) 
{ 
    dataMember.swap(c); 
} 

void CopyFrom(const MyClass &c) 
{ 
    dataMember.copyTheHardWay(c); 
} 

версия, которая принимает новый вид ссылки разрешено изменять переменную, которую он получает, потому что эта переменная ISN 't будет использоваться где-нибудь еще. Таким образом, он может «украсть» его содержимое.

В целом, эта функция была добавлена; сохранение одного типа ссылок не приведет к достижению желаемой цели.

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