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

use*_*606 9 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;
}
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时(在VS2008中)我得到了这个:错误C2664:'PrintInt':无法将参数1从'unsigned char*'转换为'const unsigned char*&'.如果我取消注释"const"注释它可以正常工作.

但是不应该指针隐式转换成const指针然后引用?期待这个工作我错了吗?谢谢!

AnT*_*AnT 11

如果指针被转换为const指针,正如您所建议的那样,那么转换的结果是一个临时值,即一个rvalue.您不能将非const引用附加到右值 - 它在C++中是非法的.

例如,由于类似的原因,此代码将无法编译

int i = 42;
double &r = i;
Run Code Online (Sandbox Code Playgroud)

尽管type int可以转换为type double,但它并不意味着您可以附加double &对该转换结果的引用.

但是,const引用(即引用-const类型的引用)可以附加到rvalue,这意味着此代码将完全编译

int i = 42;
const double &r = i;
Run Code Online (Sandbox Code Playgroud)

在您的情况下,如果您声明您的功能

void PrintInt(const unsigned char* const& ptr) // note the extra `const`
Run Code Online (Sandbox Code Playgroud)

代码将编译.


Dav*_*eas 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;             // !!!!
Run Code Online (Sandbox Code Playgroud)

如果允许转换,则上述代码将编译.一旦你已经初始化cpp(禁止的语言),他们是别名.现在,您可以使用cp指向任何常量对象,因为它是指向常量对象的指针.修改由指向的值p也是有效的代码,因为它是一个指向非const对象,但由于pcp是它会被修改常数是相同的.