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

问题描述 投票:0回答:4

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

#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 *&'。如果我取消注释“const”注释,它就可以正常工作。

但是指针不应该隐式转换为 const 指针然后引用吗?我期望这能起作用是错误的吗?谢谢!

c++ pointers reference const-correctness
4个回答
13
投票

如果按照您的建议将指针转换为 const 指针,则该转换的结果是一个临时值,即rvalue。不能将非常量引用附加到右值 - 这在 C++ 中是非法的。

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

int i = 42;
double &r = i;

即使类型

int
可以转换为类型
double
,但这仍然并不意味着您可以将
double &
引用附加到该转换的结果。

但是,const 引用(即对 const 类型的引用)可以附加到右值,这意味着该代码将完美编译

int i = 42;
const double &r = i;

在您的情况下,如果您将函数声明为

void PrintInt(const unsigned char* const& ptr) // note the extra `const`

代码将编译。


8
投票

这将打破常量正确性:

// 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
指向任何常量对象,因为它是指向 constant 对象的指针。修改
p
指向的值也是有效的代码,因为它是指向非常量对象的指针,但由于
p
cp
相同,因此将修改常量。


0
投票

我想你需要:

void PrintInt(const unsigned char* const& ptr)

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


0
投票

不能将引用转换为指针,因为指针可以为空,而引用则不能。换句话说,引用比指针更具限制性。引用始终是有效的指针,但相反的指针并不总是正确。

© www.soinside.com 2019 - 2024. All rights reserved.