没有从长unsigned int转换为long unsigned int&

时间:2012-07-10 03:44:22

标签: c++ g++

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

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

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

5 个答案:

答案 0 :(得分:6)

build的第二个参数需要引用(标有&)。引用有点像指针,因此您只能使用具有内存地址的实际变量。

这就是为什么你不能使用像index-1这样的表达式。

答案 1 :(得分:2)

非const引用只能绑定到C ++中的左值。 index-1返回一个临时的,如果绑定到引用会立即超出范围,你会有一个悬空引用。 const引用可以绑定到临时,但它会将临时的生命周期延长到const引用的生命周期。因此,如果您可以将unsigned long&更改为const unsigned long&,那么它应该有效。

答案 2 :(得分: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),具体取决于函数的总体用途。

答案 3 :(得分: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 ++的第一个版本中,int创建了一个临时类型double,其值为1,然后将该临时值传递给incr和{{ 1}}未被修改。为了防止这种意外行为,语言被更改,以便临时(即未命名的变量)不能绑定到非const引用,因为非const引用参数通常意味着将修改参数以将信息传递回呼叫者。如果以静默方式创建临时信息,则呼叫者将丢失该信息,例如

ss

如果允许非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! } 将创建临时get_ptr(err),如int,并设置错误状态在临时中,即使出现问题,get_ptr(int(err))仍然为零。

如果函数作者希望能够接受临时值,因为该参数不会用于将信息传递回调用者,那么该函数可以按值获取参数:

err

或const-reference:

void blah(int rr);

答案 4 :(得分:-1)

您的错误消息是什么行?当您需要long unsigned int引用(换言之,long unsigned int的地址)

时,您似乎传递了long unsigned int索引