2017-01-26 22 views
12

Tôi đã cố gắng hoán đổi hai biến bằng cách sử dụng std::tie() theo mã sau đây (Tôi biết là std::swap, tôi đã cố gắng hết sức này):Hành vi khác nhau khi cố gắng hoán đổi hai biến bằng cách sử dụng {} và std :: make_pair()

#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; 
} 

Tôi đã biên dịch bằng cách sử dụng g++ test.cpp -std=c++11 -o test.

Nhưng đầu ra là thế này:

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 

Vì vậy, câu hỏi của tôi là, vì chúng ta có thể viết {a, b} thay vì viết std::make_pair(a, b) mọi (C++ 11 trở đi), tại sao hai phiên bản cho đầu ra khác nhau?

tôi đoán là các dòng sau

std::tie(a, b) = {b, a}; 

không thực hiện một cặp và đối với một số lý do duy nhất đột biến giá trị của a. Nhưng tôi không chắc chắn.

+0

trông giống như hành vi không xác định ... 'a' đang được đặt thành giá trị của' b' và sau đó cập nhật 'a' được ghi thành' b' ... Vấn đề về điểm chuỗi. –

+0

@ Jarod42 đưa ra câu trả lời bên dưới. Bạn nói đúng rằng bạn có thể xây dựng một cặp với {} nhưng trình biên dịch cần phải biết rằng đó là những gì bạn đang xây dựng, tại thời điểm đó. –

Trả lời

5

{b, a} tạo std::tuple<int&, int&> trong khi std::make_pair tạo std::pair<int, int>.

Cân nhắc điều gì xảy ra với std::pair<int&, int&>. Về cơ bản nó chỉ định một trong các biến cho biến khác, và sau đó cố gắng gán một biến khác cho biến đầu tiên. Nó tương đương với việc thực hiện a = b; b = a; hoặc b = a; a = b;.

+0

Nó không tạo ra một cặp ' ', nó tạo ra một' tuple '. – Barry

13

tie(a, b) = {b, a};

sẽ sử dụng std::tuple<int&, int&> operator = (std::tuple<int&, int&>&&). và không phải std::tuple<int&, int&> operator = (std::tuple<int, int>&&) như bạn mong đợi.

std::tie(a, b)std::tuple<int&, int&>.
std::tuple có một số operator =, nhưng chỉ khả thi với (không được nhập) {a, b} là nhiệm vụ sao chép/di chuyển.

3

chỉ cần sử dụng make_tuple

std::tie(a, b) = std::make_tuple(b, a); 

nó là điều tương tự a = b hoặc b = a;

Các vấn đề liên quan