使用指向非常量字符串的指针初始化对指向常量字符串的指针的引用时出错

问题描述

嗨,我正在尝试了解引用和指针在 C++ 中的工作方式,因此尝试了不同的示例,其中一个我无法理解为什么会产生错误

int main()
{
     cout << "Hello World" << endl; 
     std::string s="hg";
     std::string *ptr=&s; 
     const std::string * &k=ptr ;
     return 0;
}

在编译这个程序时,我收到一个错误

错误:无法将“const string*& {aka const std::__cxx11::basic_string&}”类型的非常量左值引用绑定到“const string* {aka const std::”类型的右值__cxx11::basic_string}'

我的问题如下:

  1. 为什么在引用的错误中写入了 const string* 类型的右值。哪一部分是这里的右值。右侧是一个指针 ptr,它是一个左值。
  2. 如果我们从 std::string 前面删除 const 使得语句现在变成:std::string* &k=ptr 程序运行良好,我认为这是因为现在左侧和右侧的类型相同.那就是被引用的对象类型和我们去掉const后的引用类型是一样的。
  3. 现在我尝试了如下不同的语句:std::string* const& = ptr;,结果证明这也有效。所以我的问题是为什么在这种情况下代码有效,但在第一种情况下(当 const 在前面时)它不起作用? PS:我在语句中知道: const std::string * &k = ptr ; k 是对 const 字符串指针的引用,而在语句 std::string* const&k = ptr; k 是对 const 指针的引用。但为什么在一种情况下它有效,而在另一种情况下却没有?
  4. 现在,如果我将语句更改为 const std::string* const&k = ptr;,程序将再次运行。该程序如何处理此案例。

解决方法

  1. 给定 const std::string * &k=ptr ;,正如您所见,这里的类型不匹配。您正在尝试将 std::string* 绑定到对 const std::string* 的引用。引用不能直接绑定不同类型的对象,需要将std::string*转换为const std::string*,这是一个临时的,即右值,然后你得到rvalue can't be bound to的错误引用左值。

  2. std::string * &k=ptr ; 有效,因为类型匹配且不需要转换。

  3. std::string* const& k= ptr; 与 #2 相同,除了 k 是无法修改的 const 的左值引用。

  4. const std::string* const&k = ptr; 之所以有效,是因为 k 是对 const 的左值引用,它可以绑定到从 const std::string* 转换而来的临时 std::string*。 (顺便说一句,右值引用也适用。例如const std::string* &&k = ptr;