Различное поведение при попытке заменить две переменные с помощью {} и std:: make_pair()
Я пытался обменять две переменные с помощью std::tie()
в соответствии с следующим кодом (я знаю std::swap
, я просто пытался это из любопытства):
#include <iostream>
#include <tuple>
using std::cin; using std::tie;
using std::cout; using std::endl;
using std::make_pair;
int main() {
int a = 2, b = 10;
cout << "Before Swapping using {}" << endl;
cout << "a: " << a << " b: " << b < <endl;
tie(a, b) = {b, a};
cout << "After Swapping using {}" << endl;
cout << "a: " << a << " b: " << b << endl;
a = 2, b = 10;
cout << "Before Swapping using make_pair()" << endl;
cout << "a: " << a << " b: " << b << endl;
tie(a, b) = make_pair(b, a);
cout << "After Swapping using make_pair()" << endl;
cout << "a: " << a << " b: " << b << endl;
return 0;
}
Я скомпилировал его с помощью g++ test.cpp -std=c++11 -o test
.
Но результат был следующим:
Before Swapping using {}
a: 2 b: 10
After Swapping using {}
a: 10 b: 10
Before Swapping using make_pair()
a: 2 b: 10
After Swapping using make_pair()
a: 10 b: 2
Итак, мой вопрос заключается в том, что мы можем писать {a, b}
вместо того, чтобы писать std::make_pair(a, b)
каждый раз (С++ 11), почему эти две версии дают разные результаты?
Я предполагал, что следующая строка
std::tie(a, b) = {b, a};
не создает пару и по какой-то причине только мутирует значение a
. Но я не уверен.
Ответы
Ответ 1
tie(a, b) = {b, a};
будет использовать std::tuple<int&, int&> operator = (std::tuple<int&, int&>&&)
.
и не std::tuple<int&, int&> operator = (std::tuple<int, int>&&)
, как вы ожидаете.
std::tie(a, b)
- это std::tuple<int&, int&>
.
std::tuple
имеет несколько operator =
, но единственной жизнеспособной с (не типизированной) {a, b}
является назначение копирования/перемещения.
Ответ 2
{b, a}
делает std::tuple<int&, int&>
, а std::make_pair
делает std::pair<int, int>
.
Рассмотрим, что происходит с std::pair<int&, int&>
. Он по существу назначает одну из переменных другой, а затем пытается назначить другую первой. Это эквивалентно выполнению a = b; b = a;
или b = a; a = b;
.
Ответ 3
просто используйте make_tuple
std::tie(a, b) = std::make_tuple(b, a);
это то же самое a = b или b = a;