Сначала вы можете избежать ненужного кода:
int temp = num1;
num1 = num2;
num2 = temp;
Pair pair = {num1, num2};
Зачем сначала менять номера, просто создайте пару с замененными числами:
Pair pair = {num2, num1};
// ^ ^
Но теперь давайте рассмотрим различия(Я отбросил все детали, не относящиеся к проблеме, т.е. фактический обмен):
Pair& swap(Pair& pair)
{
return pair;
}
В первом варианте вы получаете пару по ссылке. Эта пара должна быть создана снаружи и передана в функцию:
Pair p; // created outside
swap(p); // swap uses reference to p outside
// p still exists
// swap returns just a reference to the same p it received
// -> you can use it for assignment:
Pair pp = swap(p);
Обратите внимание, что ваша функция поменяла местами исходный p, полученный по ссылке, поэтому оба p и pp содержат одинаковое содержимое. Таким образом, эти два фрагмента кода эквивалентны:
Pair p;
Pair pp = swap(p);
Pair p;
swap(p); // ignoring the return value
Pair pp = p;
Во втором варианте вы создаете пару внутри функции!
Pair& swap(int num1, int num2)
{
Pair pair = {num1, num2};
return pair;
}
Но время жизни парызаканчивается функцией выхода. Таким образом, вы возвращаете ссылку на пару, которая фактически уже была уничтожена, что приводит к неопределенному поведению .
Точно так же происходит, если вы принимаете пару по значению:
Pair& swap(Pair pair) // not a reference -> pair is copied into local variable
{
return pair; // returning reference to local -> undefined behaviour!
}
Во всех случаях, когда вы хотите вернуть локальные переменные, вам нужно вернуть их по значению:
Pair swap(int, int)
{
Pair pair;
return pair; // return by value, value will be copied into target variable
// (actually, due to copy elision, directly written there)
}
Возвращение по значению также может быть полезно, если вы не хотите изменять парупередан функции (просто для полноты, это не значит, что нужно , чтобы изменить свою функцию на). Однако вы должны убедиться, что не измените переданную пару. Вы можете принять по константной ссылке и создать копию внутри;тем не менее, самый простой способ - это принимать по значению, что создает копию непосредственно при получении параметра:
Pair swap(Pair pair) // notice: both references dropped
{
return pair;
};
Теперь p и pp do различаются (хорошо, если вы действительно реализовалиобмен, конечно):
Pair p;
Pair pp = swap(p);