【问题标题】:Error when Initialising a reference to a pointer to const string with pointer to a non-const string使用指向非常量字符串的指针初始化对指向 const 字符串的指针的引用时出错
【发布时间】:2021-08-03 19:03:02
【问题描述】:

您好,我正在尝试了解引用和指针在 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 左值引用绑定到 'const string* {aka const std:: 类型的右值__cxx11::basic_string}'

我的问题如下:

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

【问题讨论】:

  • 要了解为什么第一种情况不能被允许,请考虑int x = 0; int* p = &amp;x; const int*&amp; pr = p; const int y = 1; pr = &amp;y; *p = 123;,它将分配给常量对象y

标签: c++ string c++11 pointers reference


【解决方案1】:
  1. 给定const std::string * &amp;k=ptr ;,正如您所见,这里的类型不匹配。您正在尝试将std::string* 绑定到对const std::string* 的引用。引用不能直接绑定到不同类型的对象,std::string*需要转换成const std::string*,这是一个临时的,即右值,然后你得到右值不能绑定到左值引用的错误。

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

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

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

【讨论】:

  • 如果您回答的第 4 种情况,我们可以检查/确认临时对象 const std::string* 的地址和左值 std::string* 的地址不同吗?我试过cout&lt;&lt;&amp;ptr&lt;&lt;&amp;k;,这确实给了我不同的地址。这意味着它们是不同的对象,因此确实是通过临时物化创建了一个临时对象。
  • @JasonLiam 是的,你是对的。对于案例 2 和案例 3,您应该获得相同的地址。
  • 但在以下示例中不应该发生转换:int i = 34; const int &amp;j=i; 吗?在这个例子中,i 的类型是 int,而在右边我们有一个对 const int 的引用。所以类型不匹配。这会发生什么?在这种情况下会有任何转换吗? PS:我知道我们可以将 const 引用到 const 以及非常量对象。
  • @JasonLiam 不,const int &amp;j=i; 中不需要转换,j 直接绑定到i(作为对const 的引用)。对于像int* const&amp; j = i; 这样的指针也是如此。但是指向 const 和指向非 const 的指针是不同的类型(int* vs const int*),这需要隐式转换。
  • 这个 const string* temporay 对象是prvalue还是xvalue?我认为它是一个 xvalue,因为它占用了内存。如果是这种情况,您能否确认/添加。
猜你喜欢
  • 2020-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-24
  • 2013-04-26
  • 2015-06-22
  • 1970-01-01
相关资源
最近更新 更多