假设我有这个功能:
void f(int*& ptr) {
//do something
}
当我尝试做的时候:
int array[3] = {};
f(array); //fails to compile, error array is rvalue
int* p = array;
f(p); //compiles
为什么第一种情况会失败?数组是否与指针等效?
答案 0 :(得分:7)
不,数组不等同于指针。
在第一种情况下,必须将数组转换为指针。转换的结果是 rvalue ,它无法绑定到非const 左值引用,因此出错。
在第二种情况下,p
是左值,表示正确类型的对象,因此函数调用成功。
答案 1 :(得分:2)
int* p = array;
f(p); // compiles
f(array); // (this compiles too!)
数组不等同于指针,但是有一个特殊的规则,当数组的名称传递给它时,数组的名称将被自动视为指向数组第一个元素的指针函数参数,或初始化指针时(int* p = array
是int* p = &array[0]
的快捷方式)。
使用f(p)
的示例并不有趣:您只是手动将指针传递给数组的第一个元素。
int array[3] = {};
f(array); //fails to compile, error array is rvalue
在这里,"特殊情况"我谈过要申请(因此名称array
再次被视为&array[0]
),但该函数接受int*&
而不是int*
。要理解为什么会失败,请考虑一下:
#include <string>
void baz1(std::string& str) {}
void baz2(const std::string& str) {}
int main()
{
// baz1("hello world!");
// ^ Doesn't compile, because converting string literal
// to std::string would result in a *temporary*, and you
// may not bind a temporary to a reference-to-non-const
baz2("hello world!");
// ^ OK, because baz2 takes a reference-to-const
}
或者,同样的问题:
void ecl(int& x) {}
void ipse(const int& x) {}
int main()
{
// ecl(3); // doesn't compile
ipse(3); // OK
}
所以我们可以这样修理你的程序:
void f(int* const& ptr) {}
// ^^^^^
int main()
{
int array[3] = {};
f(array); // compiles!
}