当我尝试编译以下代码时,收到错误消息从long unsigned int
到long unsigned int&
的参数2没有已知转换:
void build(int* &array, unsigned long& index) {
if (index == 0)
return;
else {
heapify(array, index);
build(array, index-1);
}
}
有人可以解释为什么会发生这种情况,以及这个错误背后的逻辑是什么?
答案 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
索引