C++ 学习系列 1 -- 左值、右值与万能引用

这篇具有很好参考价值的文章主要介绍了C++ 学习系列 1 -- 左值、右值与万能引用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 何为左值?何为右值?

简单的说,左值可以放在等号的左边,右值可以放在等号的右边。

左值可以取地址,右值不能取地址。

1.1 左值举例:
  • 变量、函数或数据成员
  • 返回左值引用的表达式 如 ++x、x = 1、cout << ' '  int x = 0
1.2 右值举例:
  • 返回非引用类型的表达式
    如 x++、x + 1
  • 除字符串字面量之外的字面量如 42、true
将亡值(xvalue)
  • 隐式或显式调用函数的结果,该函数的返回类型是对所返回对象类型的右值引用
#include<string>
#include<iostream>
using namespace std;
void print(string& str)
{
    cout << "left val: " <<str << endl << endl;
}

void print(string&& str)
{
    cout << "right val: " << str <<endl << endl;
}



void print(int&& i)
{
    cout << "right val: " <<i << endl << endl;
}

void print(int& i)
{
    cout << "left val: " <<i << endl << endl;
}

int getVal(){
    return 666;
}

int main(int argc, char *argv[])
{
    string str1 = "hello 1";
    print(str1);
    print("hello 2");
    print(move(str1));

    int ab = 88;
    print(ab);
    print(++ab);
    print(ab++);

    print(getVal());

    //string& aa = "abc"; // 编译不过,左值引用不可以赋右值
    const string& bb = "abc"; // 常量左值引用可以赋右值


    return 0;
}

输出:

C++ 学习系列 1 -- 左值、右值与万能引用,学习

 1.3 左值引用与右值引用

 

规则简化如下:

左值引用   {左值}  
右值引用   {右值}
常左值引用  {右值}
string f()
{
   return "bbb";
}

int main() 
{

  string &s1 = "asd";  // error
  const string &s2 = "asd";  // ok
  const string& s3 = f();  // ok
  
  string&& a2 = "defg"; // ok
  string&& a3 = f(); // ok
  
  return 0;
}
  1.4 引入右值引用意义

  可以延长右值的生命周期,右值的生命周期可以与右值引用变量相同

2. 完美转发

2.1  转发引用

在 T 是模板参数时,T&& 的作用主要是保持值类别进行转发,它有个名字就叫“转发引用”(forwarding reference)。因为既可以是左值引用,也可以是右值引用,它也曾经被叫做“万能引用”(universal reference)。

#include<string>
#include<iostream>
using namespace std;
void print(const string& str)
{
    cout << "left val: " <<str << endl << endl;
}

void print(string&& str)
{
    cout << "right val: " << str <<endl << endl;
}

string ff()
{
    return "fff";
}

template<typename T>
void f(T&& param)
{
    print(forward<T>(param));
}

int main(int argc, char *argv[])
{
    string str1 = "hello 1";
    const string& bb = "abc";
    const string& bb2 = ff();


    f(str1); // left value
    f(bb); // left value
    f(bb2); // left value
    f("abcd"); // rightvalue
    f(ff()); // right value

    return 0;
}

输出:

C++ 学习系列 1 -- 左值、右值与万能引用,学习

 2.2  完美转发 std::forward
 2.1.1 源码解析
  • 转发左值
template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type& __t) noexcept
{ return static_cast<_Tp&&>(__t); }

先通过 remove_reference 获得类型type,定义_t为左值引用的左值变量,通过 static_cast 进行强制转换

  • 转发右值
template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
{
  static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument"
        " substituting _Tp is an lvalue reference type");
  return static_cast<_Tp&&>(__t);
}
   不同于转发左值,_t为右值引用的左值变量,除此之外中间加了一个断言,表示当不是左值的时候,也就是右值,才进行static_cast转换。
2.1.2  remove_reference 解析
template<typename _Tp>
struct remove_reference
{ typedef _Tp   type; };

// 特化版本
template<typename _Tp>
struct remove_reference<_Tp&>
{ typedef _Tp   type; };

template<typename _Tp>
struct remove_reference<_Tp&&>
{ typedef _Tp   type; };

remove_reference的作用是去除T中的引用部分,只获取其中的类型部分。无论T是左值还是右值,最后只获取它的类型部分。

现代C++之万能引用、完美转发、引用折叠 - 知乎 (zhihu.com)文章来源地址https://www.toymoban.com/news/detail-629737.html

到了这里,关于C++ 学习系列 1 -- 左值、右值与万能引用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MordernC++之左值(引用)与右值(引用)

    C++中左值与右值的概念是从C中继承而来,一种简单的定义是 左值能够出现再表达式的左边或者右边,而右值只能出现在表达式的右边 。 另一种区分左值和右值的方法是: 有名字、能取地址的值是左值,没有名字、不能取地址的值是右值 。比如上述语句中a,b, c是变量可以

    2023年04月09日
    浏览(30)
  • 【C++11】左值引用和右值引用

    需要云服务器等云产品来学习Linux的同学可以移步/--腾讯云--/--阿里云--/--华为云--/官网,轻量型云服务器低至112元/年,新用户首次下单享超低折扣。     目录 一、新的类功能 1、新的默认成员函数 2、类成员变量初始化 3、强制生成默认函数的default 4、禁止生成默认函

    2023年04月17日
    浏览(34)
  • 【送书】【C++11】左值引用和右值引用

    需要云服务器等云产品来学习Linux的同学可以移步/--腾讯云--/--阿里云--/--华为云--/官网,轻量型云服务器低至112元/年,新用户首次下单享超低折扣。     目录 一、新的类功能 1、新的默认成员函数 2、类成员变量初始化 3、强制生成默认函数的default 4、禁止生成默认函

    2023年04月09日
    浏览(27)
  • 左值引用、右值引用,std::move() 的汇编解释

    1:左值引用 引用其实还是指针,但回避了指针这个名字。由编译器完成从地址中取值。以vs2019反汇编: 如图,指针和引用的汇编代码完全一样。但引用在高级语言层面更友好,对人脑。比如可以少写一个 * 号和 - 。 ,以下是指针和引用的使用: 以上就是左值引用,引用的

    2024年02月04日
    浏览(29)
  • C++ 左值和右值

    在C++11中所有的值必属于左值、右值两者之一,右值又可以细分为纯右值、将亡值。在C++11中可以取地址的、有名字的就是左值,反之,不能取地址的、没有名字的就是右值(将亡值或纯右值)。举个例子,int a = b+c, a 就是左值,其有变量名为a,通过a可以获取该变量的地址;

    2024年02月14日
    浏览(26)
  • C++左值右值完美转发转移

    英文含义: 左值(Lvalue) : Locator value ,意味着它指向一个具体的内存位置。 右值(Rvalue) : Read value ,指的是可以读取的数据,但不一定指向一个固定的内存位置。 定义 左值 :指的是一个持久的内存地址。左值可以出现在赋值操作的左侧或右侧。例如,变量、数组的元

    2024年03月10日
    浏览(44)
  • C++面试八股文:什么是左值,什么是右值?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第16面: 面试官:什么是左值,什么是右值? 二师兄:简单来说,左值就是可以使用 符号取地址的值,而右值一般不可以使用 符号取地址。 二师兄:一般左值存在内存中,而右值存在寄存器中。 二师兄:严格意义上分,右值

    2024年02月09日
    浏览(32)
  • 【C++学习】C++11——新特性 | 右值引用 | 完美转发

    🐱作者:一只大喵咪1201 🐱专栏:《C++学习》 🔥格言: 你只管努力,剩下的交给时间! C++的发展截至到目前为止,虽然版本有很多,但是C++11则带来了数量可观的变化,其中包含了约140个新特性,以及对C++03标准中约600个缺陷的修正,这使得C++11更像是从C++98/03中孕育出的一

    2024年02月06日
    浏览(26)
  • C++:深入理解C++11新特性:Chapter3:左值和右值

    在C语言中,我们常常会提起左值(lvalue),右值(rvalue)这样的称呼,而在编译程序时,编译器有时也会报出错误信息中包含 左值,右值说法。不过左值、右值通常不是通过一个严谨的定义而为人所知。下面我通过这样一个例子,来引导大家认识: 左值,右值,左值引用,右

    2024年02月04日
    浏览(32)
  • C++右值引用,右值引用与const引用的区别

    左值:可以取地址的、有名字的变量,有持久性; 右值:一般是不可寻址的常量,或在表达式求值过程中创建的无名临时对象,短暂性的。 C++11新增了另一种引用——右值引用。这种引用可指向右值,使用声明。 右值引用只能引用临时变量和常量值。 const引用:可以引用普

    2024年01月18日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包