2012-07-10 253 views
3

我收到錯誤消息long unsigned intlong unsigned int&爲參數2沒有已知的轉換,當我嘗試編譯下面的代碼無需改裝:從長期無符號整型長unsigned int類型及

void build(int* &array, unsigned long& index) { 
    if (index == 0) 
    return; 
    else { 
    heapify(array, index); 
    build(array, index-1); 
    } 
} 

有人能解釋爲什麼這發生了,這個錯誤背後的邏輯是什麼?

+0

非常感謝大家。 – ihm 2012-07-10 03:58:25

回答

-1

你的錯誤信息是哪一行?好像你傳遞一個long unsigned int索引,當它需要一個long unsigned int引用(換句話說,long unsigned int的地址)

+0

它在'build(array,index-1);' – ihm 2012-07-10 03:48:07

+0

那麼gustav的答案就是你要找的東西 – reagan 2012-07-10 03:48:30

6

build第二個參數需要一個參考(標有&)。引用就像一個指針,所以你只能使用一個具有內存地址的實際變量。

這就是爲什麼你不能使用像index-1這樣的表達式。

2

非const引用只能綁定到C++中的左值。 index-1返回一個臨時的,如果綁定到一個引用將立即超出範圍,你會有一個懸而未決的引用。 const引用可以將綁定到一個臨時的,並且它會延長臨時的生命週期到const引用的生命週期。所以,如果你可以更改unsigned long&const unsigned long&它應該工作。

2

build的第二個參數是對unsigned long的引用。但在遞歸調用中,您將它傳遞給一個實際值(即「右值」)。

如果您按以下方式重寫函數,問題應該消失。

void build(int* &array, unsigned long& index) { 
    if (index == 0) 
    return; 
    else { 
    heapify(array,index); 
    index -= 1; 
    build(array,index); 
    } 
} 

但是請注意,這可能不是你想要的。在遞歸調用之前將更改index的值。您可能需要在調用後將其更改回去(index += 1),具體取決於函數的總體用途。

1

參見的設計與C++演進,3.7章,P86,這使本實施例中:

void incr(int& rr) { rr++; } 

void g() 
{ 
    double ss = 1; 
    incr(ss)  // note: double passed, int expected 
       // (fixed: error in Release 2.0) 
} 

在第一個版本的C++臨時從double創建int類型的,具有值1,那麼該臨時被傳遞給incr並且ss未被修改。爲了防止這種意外的行爲,語言被改變了,所以臨時的(即未命名的變量)不能綁定到非const引用,因爲非const引用參數通常意味着參數將被修改以將信息傳回給呼叫者。如果暫時被創建,則主叫方丟失該信息,例如

void* get_ptr(int& error); // sets error=0 if returned pointer is valid 

void g() 
{ 
    unsigned err = 0;  // oops, wrong type 
    void* p = get_ptr(err); // uh-oh, error status stored in temporary 
    if (err == 0)   // condition always true 
     use_ptr(p);   // uh-oh! pointer may not be valid! 
} 

如果一個非const引用是允許綁定到一個臨時那麼這個程序是很危險的,因爲get_ptr(err)會創建一個臨時int,如get_ptr(int(err)),並設置臨時的錯誤狀態,所以err仍然會即使存在問題,也是零。

如果函數的作者希望能夠接受臨時工,因爲參數不會被用來傳遞信息返回給調用者,則該功能可以通過值取參數:

void blah(int rr); 

或const-reference:

void blah(const int& rr); 
相關問題