Я провел некоторые эксперименты с ссылками на rvalue с помощью компилятора TDM-GCC 4.6.1 и сделал несколько интересных наблюдений, которые я не могу объяснить теориями. Я хотел бы, чтобы эксперты помогли мне объяснить их.
У меня есть очень простая программа, которая работает не с объектами, а с примитивами int, и в ней определены 2 функции:
foo1 (возвращая локальную переменную по ссылке rvalue) и
foo2 (возвращает локальную переменную по значению)
#include <iostream>
using namespace std;
int &&foo1();
int foo2();
int main()
{
int&& variable1 = foo1();
//cout << "My name is softwarelover." << endl;
cout << "variable1 is: " << variable1 << endl; // Prints 5.
cout << "variable1 is: " << variable1 << endl; // Prints 0.
int&& variable2 = foo2();
cout << "variable2 is: " << variable2 << endl; // Prints 5.
cout << "variable2 is still: " << variable2 << endl; // Still prints 5!
return 0;
}
int &&foo1() {
int a = 5;
return static_cast<int&&>(a);
}
int foo2() {
int a = 5;
return a;
}
Кажется, что значение, возвращаемое foo1 и полученное variable1, исчезает через некоторое время — возможно, в течение короткого периода в несколько миллисекунд. Обратите внимание, что я запретил cout печатать «Меня зовут программный любитель», комментируя его. Если я разрешу выполнение этого оператора, результат будет другим. Вместо того, чтобы печатать 5, 0, он печатает 0, 0. Похоже, что это из-за задержки, введенной «cout << «Меня зовут любитель программного обеспечения». что 5 превращается в 0.
Выше указано, как должна вести себя ссылка rvalue при обращении к примитивному целому числу, которое функция возвращает по ссылке, а не по возвращаемому значению? Кстати, почему это 0, почему не мусор?
Также обратите внимание, что переменная 2, кажется, никогда не вымирает, независимо от того, сколько раз я печатал ее с помощью cout! Переменная2 относится к примитивному целому числу, которое функция возвращает по значению, а не по ссылке.
Благодарю.
Rvalue ссылки по-прежнему просто ссылки. Ссылка на локальную переменную функции недействительна после возврата функции. Вам повезло, что ваша ссылка на rvalue равна 5 в любое время после вызова функции, потому что она технически недействительна после возврата функции.
редактироватьЯ расширяю свой ответ, надеясь, что некоторые люди сочтут некоторые дополнительные детали полезными.
Переменная, определенная внутри функции, является локальной переменной функции. Время жизни этой переменной ограничено внутри функции, в которой она была объявлена. Вы можете думать, что она «уничтожена», когда функция возвращается, но на самом деле она не уничтожена. Если это объект, то будет вызван его деструктор, но память, в которой хранится переменная, все еще там. Любые ссылки или указатели, которые у вас были на эту переменную, все еще указывают на то же место в памяти, но эта память была переопределена (или может быть переопределена в какое-то неопределенное время в будущем).
Старые значения (в вашем случае «5») еще какое-то время будут присутствовать, пока что-то не придет и не перезапишет это. Нет никакого способа узнать, как долго значения будут оставаться там, и никто никогда не должен зависеть от того, будут ли они оставаться там в течение любого периода времени после возврата из функции. Считайте, что любые ссылки (или указатели) на локальные переменные функции недействительны после возврата из функции. Образно говоря, если вы постучите в дверь, вы, вероятно, не найдете нового арендатора приемлемым.
Других решений пока нет …