我将用代码说明我的问题:
#include <iostream>
void PrintInt(const unsigned char*& ptr)
{
int data = 0;
::memcpy(&data, ptr, sizeof(data));
// advance the pointer reference.
ptr += sizeof(data);
std::cout << std::hex << data << " " << std::endl;
}
int main(int, char**)
{
unsigned char buffer[] = { 0x11, 0x11, 0x11, 0x11, 0x22, 0x22, 0x22, 0x22, };
/* const */ unsigned char* ptr = buffer;
PrintInt(ptr); // error C2664: ...
PrintInt(ptr); // error C2664: ...
return 0;
}
当我运行此代码时(在VS2008中)我得到了这个:错误C2664:'PrintInt':无法将参数1从'unsigned char *'转换为'const unsigned char *&amp;'。如果我取消注释“const”注释,它可以正常工作。
但是不应该指针隐式转换为const指针然后引用?期待这个工作我错了吗?谢谢!
答案 0 :(得分:11)
如果指针被转换为const指针,正如您所建议的那样,那么转换的结果就是一个临时值,即 rvalue 。您不能将非const引用附加到右值 - 它在C ++中是非法的。
例如,由于类似的原因,此代码无法编译
int i = 42;
double &r = i;
即使类型int
可转换为double
类型,但它仍然不代表您可以附加double &
引用到该转换的结果。
但是,const引用(即引用-const类型的引用)可以附加到rvalue,这意味着此代码将完全编译
int i = 42;
const double &r = i;
在您的情况下,如果您将您的功能声明为
void PrintInt(const unsigned char* const& ptr) // note the extra `const`
代码将编译。
答案 1 :(得分:7)
这将破坏常态:
// if it was allowed
const int x = 5;
int *p;
const int*& cp = p; // cp is a ´constant´ alias to p
cp = &x; // make cp (and p) point to a constant
*p = 7; // !!!!
如果允许转换,则上述代码将编译。使用cp
(语言禁止)初始化p
后,它们就是别名。现在,您可以使用cp
指向任何常量对象,因为它是指向常量对象的指针。修改p
指向的值也是有效代码,因为它是指向非const对象的指针,但由于p
和cp
相同,因此它将修改常量。
答案 2 :(得分:0)
我认为你需要:
void PrintInt(const unsigned char* const& ptr)
如果你想通过引用传递一个const指针。
答案 3 :(得分:0)
您无法将引用转换为指针,因为指针可以为null而引用不能。换句话说,引用比指针更具限制性。引用始终是有效指针,但反之并非总是如此。