4

当我尝试编译以下代码时,我收到错误消息No known conversion for argument 2 from long unsigned intto :long unsigned int&

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

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

4

5 回答 5

6

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

这就是为什么你不能使用像index-1.

于 2012-07-10T03:47:33.120 回答
2

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

于 2012-07-10T03:49:33.283 回答
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在调用后将其改回 ( ),具体取决于函数的总体用途。

于 2012-07-10T03:49:47.683 回答
1

请参阅The Design and Evolution of 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++ 的第一个版本中,使用 valueint创建了一个临时类型,然后该临时被传递给并且没有被修改。为了防止这种意外行为,更改了语言,以便临时(即未命名的变量)不能绑定到非常量引用,因为非常量引用参数通常意味着将修改参数以将信息传递回呼叫者。如果一个临时的被静默创建,调用者会丢失该信息,例如double1incrss

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,like get_ptr(int(err)),并在临时对象中设置错误状态,所以err即使出现问题,它仍然是零。

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

void blah(int rr);

或通过常量引用:

void blah(const int& rr);
于 2012-07-10T19:58:16.007 回答
-1

你的错误信息在哪一行?看起来你正在传递一个long unsigned intfor 索引,当它需要一个long unsigned int引用时(换句话说,的地址long unsigned int

于 2012-07-10T03:47:23.643 回答