2012-02-24 67 views
0
namespace pairDemo{ 

template<typename L, typename R> 
class pair{ 
public: 

    pair(const L& left,const R& right) 
     :lft(left),rht(right) 
    { 
    } 

    pair(const pair<L,R>& p) 
     :lft(p.lft),rht(p.rht) 
    { 
    } 

    L left() const{ 
     return lft; 
    } 
    R right() const{ 
     return rht; 
    } 

    void left(const L& left){ 
     lft = left; 
    } 
    void right(const R& right){ 
     rht = right; 
    } 
private: 
    L lft; 
    R rht; 
}; 
} 

// ------------------------------------------- --------關鍵字「const」如何工作?

#include "pairTemp.h" 
#include <iostream> 
using namespace std; 

pairDemo::pair<int, double> func(int x, double y){ 
    pairDemo::pair<int, double> temp(x*2, x+y); 
    return temp; 
} 

int main(){ 
    int x = 2; double y = 3.55; 
    pairDemo::pair<int, double> myPair = func(x,y); 
    cout << myPair.left() << myPair.right(); 
} 

我有一個問題,構造函數的參數,如果我不宣佈「常量」,函數func()將有一個錯誤。我不知道爲什麼,任何人都可以幫助我。

+0

如果你沒有聲明什麼'const'?你得到的錯誤是...? – 2012-02-24 21:59:38

+0

你不在哪裏聲明const,什麼是錯誤,以及錯誤是哪一行? – 2012-02-24 22:00:11

+0

構造函數參數中的「const」。如果我沒有delcare,func()會有一個錯誤,它不能將int轉換爲int&。現在我知道臨時應該使用const了。 – titus 2012-02-24 22:42:47

回答

1

如果從構造pair::pair(const L& left,const R& right)刪除const當時的因爲x*2結果綁定到L& leftx+y禁止代碼pairDemo::pair<int, double> temp(x*2, x+y);將無法​​正常工作從結合R& right禁止。

C++有此規則,因爲設計者認爲非const引用類型的函數參數應表明,該函數可以改變值,並且該該變化應給調用者可見。

考慮:

void foo(int &i) { 
    i = 3; 
} 

foo(x); // sets x to 3 
foo(1); // sets 1 to 3??? prohibited 

這可能會導致混亂,如果有人不小心與臨時像1或或x+yx*2調用foo,所以C++決定做安全的事情,而不是讓這些編譯。

C++ 11增加了'右值引用',它們有一些不同的規則。

void bar(int &&i) { // && means 'rvalue reference' 
    i = 3; 
} 

bar(1); // sets 1 to 3! 
bar(x); // prohibited. 

右值引用應該表示該函數正在獲取一個臨時值,並且它所做的任何操作都不會影響外界。現在危險的是,一個採用右值引用的函數會被意外地用非臨時函數調用。因此,這些規則試圖禁止您傳入非臨時值,如x

+0

現在我知道臨時應該使用const。 – titus 2012-02-24 22:45:51

2

由於您將x * 2和x + y傳遞給構造函數,因此必須將引用聲明爲const(即只讀)。

如果您傳遞的是非const(即讀寫)引用,那麼函數的代碼將能夠修改引用以更改任何傳入的值。如果您正在傳遞x,y,因爲代碼可以想象更新這些值。

但是在這種情況下,更改x * 2或x + y的值是沒有意義的,編譯器堅持引用是const。

+0

添加const從來不是一個問題,我相信,當你試圖去除你碰到的const限定符時遇到麻煩,對吧? 哦,但錯誤是如果他刪除const,正確,從不知道 – 2012-02-24 22:04:25

+0

@DanF如果您依賴於能夠修改引用的對象,那麼添加'const'是一個問題。 – hvd 2012-02-24 22:05:21

1
pair(const L& left,const R& right) 
     : lft(left), rht(right) 
{ 
} 

pairDemo::pair<int, double> func(int x, double y) 
{ 
    pairDemo::pair<int, double> temp(x*2, x+y); 
    return temp;    // ^^^ ^^^ 
}        // temporaries here 

您的構造函數通過引用獲取其參數。在func中,您將臨時對象傳遞給此構造函數。臨時對象只能綁定到const引用,這就是爲什麼如果刪除const就會出現錯誤。如果您選擇按值傳遞參數,則可以省略const限定符。

+0

謝謝,我知道。 – titus 2012-02-24 22:37:14

1

是的,如果您有類型int &的參數,則無法傳遞參數x * 2。使用非const引用參數可以修改參數,如果您決定忽略這些修改(如果有),則需要明確地進行修改。

至於傳遞x * 2const int &,它可能是一個有點奇怪的作品,但實際發生的事情是,一個新的臨時變量被創建,分配x * 2變量是什麼獲取傳遞給函數。在這種情況下,自動創建一個臨時對象沒有問題,因爲它的值不會被改變(這就是爲什麼你有const,不是嗎?)。