2017-10-16 109 views
2
#include <iostream> 
using namespace std; 

template <class T> 
void swap1(T& a, T& b) { 
    T c = a; 
    a = b; 
    b = c; 
} 

int main() { 
    int n1 = 5; 
    int n2 = 7; 
    swap1(n1, n2); 
    cout << n1 << " " << n2 << endl; 

    int *p1 = &n1; 
    int *p2 = &n2; 
    swap1(*p1, *p2); 
    cout << n1 << " "<< n2 << endl; 
} 

在許多語言中,當您調用函數時,首先評估其參數,然後將函數應用於評估結果。使用參考參數評估函數

但是,如果我們在此遵循此規則,則swap1(n1, n2)swap1(*p1, *p2)都將評估爲swap1(5, 7),這是沒有意義的。

那麼,這種情況下的評估規則是什麼?另外,在C++中通常評估函數的規則是什麼?

+0

在函數內部,參數'a'和'b' ***從'main'函數引用***變量*'n1'和'n2'。您不會傳入這些變量的*值*。使用解引用的指針並不重要,因爲這些指針指向'n1'和'n2'。 –

+0

考慮像'int n = 2; n ++;'你會堅持相當於'2 ++'...嗎?提示:研究自C開始以來已知的l值和r值之間的差異。 – CiaPan

+1

評估左值並不意味着訪問存儲的值;評估'* p1'的結果是該內存位置的標識符,而不是'5'。然後,當函數參數初始化時:使用左值表達式初始化引用參數的作用是將引用綁定到表達式(再次訪問內存位置) –

回答

2

在許多語言中,當您調用一個函數時,首先評估它的參數,然後將函數應用於評估結果。

這正是C++中發生的情況。但是,我們必須分析「評估一個函數的論點」的實際含義。在C++中,它的意思是「使用指定爲參數的表達式複製參數初始化」。複製初始化C++引用的方法是綁定到由初始化程序設計的實體。在左值引用的情況下(如在您的swap中),這意味着初始值必須是左值。 n1是一個左值,因此是*p1。由於參考文獻需要一個左值,這就是所有的評估。

如果該參數是值類型(不是引用),則左值到右值轉換將應用於初始化該值。但是因爲我們正在初始化一個參考,所以這種轉換不會發生。