【问题标题】:why no implicit conversion from pointer to reference to const pointer为什么没有从指针到引用到 const 指针的隐式转换
【发布时间】:2011-02-23 21:27:32
【问题描述】:

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

#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' : cannot convert parameter 1 from 'unsigned char *' to 'const unsigned char *&'。如果我取消注释“const”注释,它可以正常工作。

但是,不应该指向指向const指针,然后采取引用?我期望这行得通是错的吗?谢谢!

【问题讨论】:

    标签: c++ pointers reference


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      这将破坏 const 正确性:

      // 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;             // !!!!
      

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

      【讨论】:

        【解决方案3】:

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

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

        int i = 42;
        double &r = i;
        

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

        然而,一个 const 引用(即引用到 const 类型的引用)可以附加到一个右值,这意味着这段代码可以编译得很好

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

        如果您将函数声明为

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

        代码将编译。

        【讨论】:

        • 是的,他说的 :) 函数签名需要一个 const 引用:虽然通过引用传递指针有点没有意义,因为指针和引用无论如何都需要相同的大小......
        • 这不正确。与大小相同的指针相比,引用更可能为零大小。
        【解决方案4】:

        我认为你需要:

        void PrintInt(const unsigned char* const&amp; ptr)

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

        【讨论】:

        • 通过引用到常量传递指针有什么意义?为什么不直接按值传递指针?
        • @Fred 没错,我不会打扰;看我的评论@AndreyT :)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-15
        • 2011-01-14
        • 1970-01-01
        相关资源
        最近更新 更多