为什么没有从指针到const指针的引用的隐式转换

时间:2010-05-25 20:24:15

标签: c++ pointers reference

我将用代码说明我的问题:

#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指针然后引用?期待这个工作我错了吗?谢谢!

4 个答案:

答案 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对象的指针,但由于pcp相同,因此它将修改常量。

答案 2 :(得分:0)

我认为你需要:

void PrintInt(const unsigned char* const& ptr)

如果你想通过引用传递一个const指针。

答案 3 :(得分:0)

您无法将引用转换为指针,因为指针可以为null而引用不能。换句话说,引用比指针更具限制性。引用始终是有效指针,但反之并非总是如此。