2013-11-26 25 views
5

Trong đoạn mã sau:C++ nonconst const chức năng tham khảo quá tải

int foo(const int& f) //version 1 
{ 
    int g = f; 
    return int(foo(g)); // calls itself, turning into SO 
} 

int& foo(int& f) //version 2 
{ 
    f *= -1; 
    return f; 
} 

int main() 
{ 
    int f = 11; 
    cout << foo(f) << endl; 
    cout << foo(22) << endl; 
} 

Các bản in cout đầu tiên -11 như mong đợi; f là lvalue, vì vậy nó liên kết với phiên bản thứ hai của foo (mặc dù nó có thể liên kết với phiên bản thứ nhất, phiên bản thứ 2 đó là kết hợp tốt hơn).

Cuộc gọi thứ hai là foo đang sử dụng giá trị làm tham số, do đó, phiên bản duy nhất khả thi của foo là phiên bản đầu tiên. Càng xa càng tốt. Bên trong phiên bản đầu tiên của foo, tôi đã tạo một bản sao của thông số để tôi có thể gọi phiên bản thứ hai (với số lvalue) và trả lại một bản sao sau khi cuộc gọi của phiên bản thứ hai là foo. Điều này sẽ biến thành tràn ngăn xếp; vẫn là phiên bản đầu tiên của foo sẽ được gọi.

Có thể ai đó vui lòng giải thích cho tôi biết tại sao điều này xảy ra? Tôi mong đợi rằng g bên trong phiên bản đầu tiên của foo để liên kết với phiên bản thứ hai của foo khi được chuyển làm tham số.

+3

Làm thế nào để 'foo' đầu tiên biết về' foo' thứ hai? –

Trả lời

10

Thật đơn giản - foo tại thời điểm đó chỉ có nghĩa là foo(const int& f). Không có lựa chọn thứ hai. Chưa. Chuyển đổi các định nghĩa. Hoặc tách chúng:

int foo(const int& f); 
int& foo(int& f); 

int main() 
{ 
    int f = 11; 
    cout << foo(f) << endl; 
    cout << foo(22) << endl; 
} 


int foo(const int& f) //version 1 
{ 
    int g = f; 
    return int(foo(g)); // calls itself, turning into SO 
} 

int& foo(int& f) //version 2 
{ 
    f *= -1; 
    return f; 
} 
+0

Vâng, thật dễ dàng ... – user1019710

2

Khai báo đầu tiên của foo không có ý tưởng về sự tồn tại của thứ hai. Hãy thử điều này:

int foo(int& f); 
int foo(const int& f) //version 1 
{ 
    int g = f; 
    return int(foo(g)); // calls itself, turning into SO 
} 
1

Khi trình biên dịch đạt dòng:

return int(foo(g)) 

Nó không biết về phiên bản quá tải của bạn 2. Thêm tờ khai nguyên mẫu để phía trên cùng của file:

int foo(const int& f); 
int& foo(int& f); 

Bằng cách này trình biên dịch sẽ biết về sự tồn tại của phiên bản 2 và có thể xem xét nó khi làm việc ra whith foo để gọi.

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