【问题标题】:Does the C++ Arrow Operator (->) return an lvalue in all cases?C++ 箭头运算符 (->) 在所有情况下都返回左值吗?
【发布时间】:2019-12-05 14:08:34
【问题描述】:

根据 C++ Primer 一书,“箭头运算符需要一个指针操作数并产生一个左值”。总是这样吗?例如:

#include<iostream>
#include<string>

using std::string; using std::vector;

int main()
{
     vector<string> temp {"aaa", "bbb", "ccc"};
     vector<string>::iterator iter_str = temp.begin();
     bool result = iter_str->empty();  //the result of iter_str->empty() is not an lvalue right?

     return 0;
}
  • 当我们以表达式 iter_str->empty() 为例时,它不能是赋值运算符的左操作数吗?
  • 如果箭头操作符返回一个左值,它不是一直都必须这样做吗?或者这条规则有例外吗?

【问题讨论】:

  • 这里箭头运算符的结果就是成员函数std::string::empty,是一个左值。尽管该值根本无法使用,除非立即调用它;函数调用运算符的结果是bool类型的右值。
  • @aschepler,这意味着 iter_str->empty() 的返回值实际上不是布尔值,而是字符串中的 empty() 方法对吗?并且该值立即作为一种方法执行,它的值是我收到的输出。好的,谢谢,但是 empty() 方法本身如何是左值,因为它不能位于赋值运算符的右侧,这让我感到困惑。
  • @aschepler 好答案 - 应该作为一个发布!

标签: c++ c++11


【解决方案1】:

这本书的意思是iter_str-&gt; 产生一个左值,即您正在使用的对象的值类别是一个左值。 iter_str-&gt;empty() 的整个表达式仍然是一个右值,因为 empty 按值返回。以像这样的类为例

struct integer {
    int x;
    int& ref() & {
        return x;
    }
};

这里,ref 只能合法地在左值对象上调用,因为 ref-qualifier。如果我们有这样的功能

integer* get_integer_ptr() { return new integer; }

那么我们可以合法地做

int foo = get_integer_ptr()->ref();

即使指针是右值,它也正在访问左值对象,因此对ref 的调用是合法的。


是的,存在内存泄漏,但出于示例的目的,我们可以忽略它。

【讨论】:

  • 这很好用,主要是因为 ref() 返回一个对可修改的左值对象(x) 的引用,但是如果它返回一个像上面这样的函数,它不能在左边的操作数上怎么办?赋值运算符?或者 (x) 被定义为一个常量?
  • @octopus 如果ref 刚刚返回了int,它仍然可以,请参阅this live example。请记住,当您执行ptr-&gt;function() 时,编译器所做的是将其更改为(*ptr).function()*ptr 产生一个左值,这就是为什么说箭头运算符产生一个左值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-04-28
  • 2011-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-12
  • 1970-01-01
相关资源
最近更新 更多