简体   繁体   English

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

[英]No conversion from long unsigned int to long unsigned int&

I receive the error message No known conversion for argument 2 from long unsigned int to long unsigned int& when I try to compile the following code: 我收到错误消息没有已知的转换参数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);
  }
}

Can someone explain why this happens, and what the logic is behind this error? 有人可以解释为什么会发生这种情况,这个错误背后的逻辑是什么?

The second argument of build requires a reference (marked with & ). build的第二个参数需要引用(用&标记)。 A reference is kind of like a pointer, so you can only use an actual variable that has a memory address. 引用有点像指针,因此您只能使用具有内存地址的实际变量。

This is why you can't use an expression like index-1 . 这就是为什么你不能使用像index-1这样的表达式。

A non-const reference may only be bound to an lvalue in C++. 非const引用只能绑定到C ++中的左值。 index-1 returns a temporary, which, if bound to a reference would immediately go out of scope and you would have a dangling reference. index-1返回一个临时的,如果绑定到引用将立即超出范围,你将有一个悬空引用。 A const reference can be bound to a temporary though, and it will prolong the lifetime of the temporary to the lifetime of the const reference. 虽然const引用可以绑定到临时引用,但它会将临时引用的生命周期延长到const引用的生命周期。 So, if you can change unsigned long& to const unsigned long& it should work. 所以,如果你可以改变unsigned long& const unsigned long&那么它应该可行。

The second argument of build is a reference to unsigned long . build的第二个参数是对unsigned long的引用。 But in the recursive call, you pass it an actual value (ie an "rvalue"). 但是在递归调用中,你传递一个实际值(即“rvalue”)。

If you rewrite the function as follows, the problem should disappear. 如果您按如下方式重写函数,问题应该消失。

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

But note that this might not be what you want. 但请注意,这可能不是您想要的。 The value of index will be changed before the recursive call. index的值将在递归调用之前更改。 You might want to change it back ( index += 1 ) after the call, depending on what the overall purpose of the function is. 您可能希望在调用后将其更改回来( index += 1 ),具体取决于函数的总体用途。

See The Design and Evolution of C++ , chapter 3.7, p86, which gives this example: 请参阅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)
}

In the first version of C++ a temporary of type int was created from the double , with value 1 , then that temporary was passed to incr and ss was not modified. 在C ++的第一个版本中,从double创建了一个临时类型为int值,值为1 ,然后将临时值传递给incr并且未修改ss To prevent this sort of unexpected behaviour the language was changed so that a temporary (ie an unnamed variable) cannot bind to a non-const reference, because a non-const reference parameter usually implies the parameter will be modified to pass information back to the caller. 为了防止这种意外行为,语言被更改,以便临时(即未命名的变量)不能绑定到非const引用,因为非const引用参数通常意味着将修改参数以将信息传递回呼叫者。 If a temporary is silently created the caller loses that information, eg 如果静默创建临时,则呼叫者丢失该信息,例如

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!
}

If a non-const reference is allowed to bind to a temporary then this program is dangerous, because get_ptr(err) will create a temporary int , like get_ptr(int(err)) , and set the error status in the temporary, so err will still be zero even if there's a problem. 如果允许非const引用绑定到临时,则此程序是危险的,因为get_ptr(err)将创建临时int ,如get_ptr(int(err)) ,并在临时中设置错误状态,因此err即使出现问题,仍然会为零。

If the function author wants to be able to accept temporaries, because the argument won't be used to pass information back to the caller, then the function can take parameters by value: 如果函数作者希望能够接受临时值,因为该参数不会用于将信息传递回调用者,那么该函数可以按值获取参数:

void blah(int rr);

or by const-reference: 或者通过const-reference:

void blah(const int& rr);

what line is your error message on? 你的错误信息在哪一行? It seems like you are passing in a long unsigned int for index, when it needs a long unsigned int by reference (in other words the address of the long unsigned int ) 看起来你传入一个long unsigned int for index,当它需要一个long unsigned int引用时(换句话说就是long unsigned int的地址)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM