2012-07-10 81 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); 
相关问题