无法将长无符号整数转换为长无符号整数&。

4

在尝试编译以下代码时,我收到了错误消息参数2没有已知的转换从long unsigned intlong unsigned int&

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

可以有人解释一下为什么会发生这种情况,以及这个错误背后的逻辑是什么?
5个回答

6
build的第二个参数需要一个引用(用&标记)。引用有点像指针,因此您只能使用具有内存地址的实际变量。这就是为什么您不能使用表达式index-1的原因。

2
在C++中,非const引用只能绑定到左值。 index-1返回一个临时值,如果将其绑定到引用,它将立即超出范围,并且您将拥有悬空引用。然而,const引用可以绑定到临时值,并且它将延长临时值的生命周期直到const引用的生命周期结束。因此,如果您可以将unsigned long&更改为const unsigned long&,则应该可以正常工作。

2
build的第二个参数是对unsigned long的引用。但是在递归调用中,你传递给它一个实际值(即“rvalue”)。
如果你按照以下方式重写函数,问题应该就会消失。
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章,第86页,其中给出了以下示例:
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);

或者通过常量引用:

void blah(const int& rr);

-1
你的错误信息在哪一行?看起来你正在传递一个 long unsigned int 作为索引,但它需要通过引用传递一个 long unsigned int(换句话说,是 long unsigned int 的地址)。

它在 build(array,index-1); 上。 - ihm
那么Gustav的答案就是你正在寻找的。 - reagan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接