C++ Primer:对begin()的引用

£神魔★判官ぃ 2023-07-22 09:20 72阅读 0赞

1. 问题

  1. // 编译环境:MinGW
  2. #include <iostream>
  3. #include <vector>
  4. using namespace std;
  5. int main()
  6. {
  7. vector<int> v{1, 2, 3};
  8. vector<int>::iterator i1 = v.begin();
  9. //问题:为何i2报错,而i3无错?
  10. vector<int>::iterator &i2 = v.begin();
  11. const vector<int>::iterator &i3 = v.begin();
  12. return 0;
  13. }

运行结果

2. 分析与解答

  1. i3是常量引用,i2是对非常量的引用。

    vector::iterator &i2 = v.begin();
    const vector::iterator &i3 = v.begin();

  2. v.begin()实际上返回一个右值的临时变量,非常量引用不能绑定临时变量。故i2报错,i3无错。

3. 拓展

3.1 实例1

  1. // 编译环境:MinGW
  2. #include <iostream>
  3. using namespace std;
  4. int main()
  5. {
  6. int i = 0;
  7. //为何(i++) = 1;报错,而(++i) = 1;无错?
  8. (i++) = 1;
  9. (++i) = 1;
  10. return 0;
  11. }

编译报错

解答:

  1. i++返回一个右值的临时变量,右值不可赋值。

    (i++) = 1;

  2. ++i返回一个左值的临时变量,左值可修改。

    (++i) = 1;

3.2 实例2

  1. // 编译环境:MinGW
  2. #include <iostream>
  3. #include <vector>
  4. using namespace std;
  5. int main()
  6. {
  7. vector<int> v{1, 2, 3};
  8. vector<int>::iterator i1 = v.begin();
  9. // vector<int>::iterator &i2 = v.begin();
  10. const vector<int>::iterator &i3 = v.begin();
  11. //问题:v.begin()返回右值,为何可以在等号左边?
  12. cout << *v.begin() << endl;
  13. v.begin() = v.begin() + 1;
  14. cout << *v.begin() << endl;
  15. return 0;
  16. }

运行结果

解答:

  1. v.begin()返回的临时变量是类类型,它可以调用其成员函数,实际如下表达式中的”=”不是在赋值,而是在调用成员函数。

    v.begin() = v.begin() + 1;

4. 总结

  1. 只有常量引用才能绑定临时变量,非常量引用不行。
  2. 临时变量是右值时,不可以赋值,但可以调用成员函数。或者说内置类型的右值临时变量不可以赋值,类类型的右值临时变量可以通过调用其成员函数是实现赋值。

发表评论

表情:
评论列表 (有 0 条评论,72人围观)

还没有评论,来说两句吧...

相关阅读

    相关 C++Primer学习之一引用和指针

    一.引用 引用是一种复合类型,引用分为左值引用和右值引用,其中右值引用时C++11提出来的, 常说的引用其意为左值引用。注意:引用不是对象,它是一个对象(变量)的别名,

    相关 C++ 术语(C++ Primer

    argument(实参):传递给被调用函数的值。 block(块):花括号括起来的语句序列。 buffer(缓冲区):一段用来存放数据的存储区域。IO 设备常存储输入(