首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

防止非常量左值解析为右值引用而不是const左值引用

防止非常量左值解析为右值引用而不是const左值引用:

在C++11中,引入了右值引用和const左值引用的概念,以便更好地处理临时对象和减少不必要的拷贝。当我们使用右值引用时,我们可以避免不必要的拷贝,从而提高代码的性能。但是,如果我们使用非常量左值解析为右值引用而不是const左值引用,我们可能会遇到一些问题,因为这可能会导致临时对象被修改或者被意外地转换为右值引用。

为了避免这种情况,我们可以使用const左值引用来代替右值引用。const左值引用可以绑定到临时对象上,但是它不能修改临时对象的值,从而避免了意外的修改和转换为右值引用的问题。

例如,假设我们有一个函数,它接受一个右值引用作为参数:

代码语言:cpp
复制
void foo(int&& rvalue_ref) {
    // ...
}

我们可以将这个函数修改为接受一个const左值引用作为参数:

代码语言:cpp
复制
void foo(const int& const_lvalue_ref) {
    // ...
}

这样,我们就可以避免非常量左值解析为右值引用而不是const左值引用的问题,并且我们的代码将更加安全和高效。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

引用引用

; 比方: int i=0;// i是, 0是 2、引用: c++98中的引用很常见了,就是给变量取了个别名,在c++11中,因为增加了引用(rvalue reference)的概念,所以...;   //getTemp()的返回(临时变量) 总结一下,其中T是一个具体类型: 引用, 使用 T&, 只能绑定引用, 使用 T&&, 只能绑定常量, 使用 const...T&, 既可以绑定又可以绑定; 已命名的引用,编译器会认为是个; 编译器有返回优化,但不要过于依赖; Q:下面涉及到一个问题:x的类型是引用,指向一个,但x本身是还是呢...移动构造的函数声明如下: class_name ( class_name && ); 5、引用的意义: 直观意义:临时变量续命,也就是续命,因为在表达式结束后就消亡了,如果想继续使用...参考:[c++11]我理解的引用、移动语义和完美转发 https://www.jianshu.com/p/d19fc8447eaa C++ 11 引用引用,std::move

75610

引用引用

前言 (引用作为指针的完全替代品,不仅降低了用户的编写难度,又由于其直接作为别名的特点,不用申请新空间去保存由于赋值、函数返回等引起的不必要的拷贝中产生的临时变量,而提升了效率。...如:字面常量、表达式返回,函数返回(这个不能是引用返回)等等,可以出现在赋值符号的右边,但是不能出现出现在赋值符号的左边,不能取地址。...(不是引用的重点使用场景) 先来看一段代码: int main() { double x = 1.1, y = 2.2; int&& rr1 = 10; const double&& rr2...//(修改的是初始化的"常量"10吗?如果不是那是修改的那个变量?)...如果不想rr1被修改,可以用const int&& rr1 去引用,是不是感觉很神奇。

42320

引用引用、移动语句(2)「建议收藏」

以下来自IBM知识中心 表达式可以分为以下类别之一: Lvalue:如果表达式不是const限定的,则表达式可以出现在赋值表达式的左侧。 x:要过期的引用。...以下表达式是xvalues: 调用返回类型引用类型的函数的结果 强制转换为值参考 通过xvalue表达式访问的引用类型的静态数据成员 指向成员访问表达式的指针,其中第一个操作数是xvalue...;9.str1+str2是调用了+操作符,+操作符返回的是一个string(不可以对其取地址),故其为;10.m是一个常量引用引用到一个,但引用本身是一个持久对象(可以对其取地址),。...区分清楚了,我们再来看看引用引用根据其修饰符的不同,可以分为·常量引用常量引用引用引用 引用就是对一个进行引用的类型。...这是因为在move构造函数中,s虽然是一个非常量引用,但其本身却是一个(是持久对象,可以对其取地址),因此调用*this = s时,会使用拷贝赋值函数不是move赋值函数,而这已与move构造函数的语义不相符

2.5K20

与常引用

通俗来讲,凡是可以出现在赋值运算符左边的表达式都是。与相对的就是(Rvalue),只能出现在赋值运算右边的表达式都是,所以,一定可以作为一定不能作为。...由此可以,并不是只有单个变量才能作为,也不能仅由表达式的外在形式判断它是否,需要根据一个表达式的运算结果的性质进行判断。...可见,将函数的参数声明为常引用,不完全是因为参数的在函数体内不能修改,还考虑了接受作为函数实参的情况。...3.常引用的特殊性质 对某个变量(或表达式)建立常引用时,允许发生类型转换,一般的引用则不允许,见下面的程序。...需要注意,无名临时变量具有常量性与能否作为没有必然联系,并不是所有类型的无名临时变量都不能作为文字常量构建的临时变量是可以作为被赋值的,比如类的临时对象。具体参见:临时变量的常量性。

1.1K10

C++ 与常引用

通俗来讲,凡是可以出现在赋值运算符左边的表达式都是。与相对的就是(Rvalue),只能出现在赋值运算右边的表达式都是,所以,一定可以作为一定不能作为。...由此可以,并不是只有单个变量才能作为,也不能仅由表达式的外在形式判断它是否,需要根据一个表达式的运算结果的性质进行判断。...可见,将函数的参数声明为常引用,不完全是因为参数的在函数体内不能修改,还考虑了接受作为函数实参的情况。...3.常引用的特殊性质 对某个变量(或表达式)建立常引用时,允许发生类型转换,一般的引用则不允许,见下面的程序。...需要注意,无名临时变量具有常量性与能否作为没有必然联系,并不是所有类型的无名临时变量都不能作为文字常量构建的临时变量是可以作为被赋值的,比如类的临时对象。具体参见:临时变量的常量性。

47420

【C++11特性篇】一文助小白轻松理解 C++中的【引用】【引用

引用】&【引用】 【1】引用 是一个表示数据的表达式 如: 变量名或解引用的指针 出现位置: 可以出现在赋值符号的左边,右边 性质1:可以 取地址+...可以对它赋值 性质2: 定义时const修饰符后的 , 不可以对它赋值 ,但是 可以对它取地址 引用引用就是给引用,给取别名 int a = 0; int& r1 = a...int a = 0; int& r1 = a; } 【2】引用 也是一个表示数据的表达式 如: 字面常量、表达式返回,函数返回(这个不能是引用返回)等等、 出现位置: 可以出现在赋值符号的右边...引用是 取别名 引用:给取别名————————(1)正常引用(2)带const引用 引用:给取别名 move( )可以让里面的具有 性质 引用引用...// const引用可以 const int& r2 = 10; const double& r3 = x + y; // 引用:给取别名 int&& r5 = 10; double

18110

什么是引用?跟有什么关系?

引用 引用是C++11中引入的新特性 , 它实现了转移语义和精确传递。 它的主要目的有两个方面: 消除两个对象交互时不必要的对象拷贝,节省运算存储资源,提高效率。...的概念: :能对表达式取地址、或具名对象/变量。一般指表达式结束后依然存在的持久对象。 :不能对表达式取地址,或匿名对象。一般指表达式结束就不再存在的临时对象。...引用引用的区别: 可以寻址,不可以。 可以被赋值,不可以被赋值,可以用来给赋值。...可变,不可变(仅对基础类型适用,用户自定义类型引用可以通过成员函数改变)。

1.7K20

【C++11特性篇】探究【引用(移动语义)】是如何大大提高效率?——对比【拷贝构造&引用

&引用】和【引用】基础知识 相关基础知识知识点在YY的这篇博客中有详细说明:传送门 二.普通传返回 关于 深浅拷贝 ,在YY的这篇博客里有详细的介绍:传送门->【C++】STL容器...引用作为返回/参数 1)引用的使用场景: 做参数 做返回 都能够提高效率 ————>因为减少了 拷贝 void func1(bit::string s) {} void func2(const...(char ch) 传引用没有拷贝提高了效率 s1 += '!'...; return 0; } 2)引用的缺陷: 但是当函数返回对象是一个 局部变量,出了函数作用域就不存在了,就不能使用引用返回, 只能传返回。...什么时候【移动构造(引用)】?

16710

【C++11特性篇】引用变量的属性会被编译器识别成【详解&证明&代码演示】

一.关于【引用】【引用】易混淆的知识点 【1】结论:引用变量的属性会被编译器识别成 引用变量的属性会被编译器识别成 否则在移动构造的场景下无法完成 资源转移(移动构造),必须要修改...a; int&& rr = move(a);//std::move()函数位于头文件中,该函数名字具有迷惑性,它并不搬移任何东西 //唯一的功能就是将一个强制转化为引用...,然后实现移动语义 cout << &r << endl; cout << &rr << endl; //我们知道不能取地址,不能被修改,而这里都能正常打印...//证明结论:引用变量的属性会被编译器识别成 return 0; }

9210

C++ 中的

四、的转换 一个可以被转换(convert),这完全合法且经常发生。...一个volitile的数字常量)如果想要被引用,需要先变成一个。如果那被允许,你就可以通过它的引用来改变数字常量。相当没有意义,不是吗?...’ from an rvalue of type ‘int’ GCC认为引用不是const的,即一个常量。...现在被修改的问题被很好地解决了。同样,这不是一个技术限制,而是C ++人员避免愚蠢麻烦所作的选择。 应用:C++中经常通过常量引用来将传入函数中,这避免了不必要的临时对象的创建和拷贝。...前文说到,const)可以被修改(赋值),但不能。但C++11引入的引用特性,打破了这个限制,允许我们获取引用,并修改之。

1.8K20

【Modern C++】深入理解

C++11之前,遵循了C语言的分类法,但与C不同的是,其将表达式统称为,函数,并添加了引用能绑定到但唯有const引用能绑定到的规则。...rvalue可以影响函数重载:当被用作函数实参且该函数有两种重载可用,其中之一接受引用的形参另一个接受 const引用的形参时,将被绑定到引用的重载之上。...,s是一个引用a是一个const 引用。...这是因为10是常量常量,一个怎么能够被引用引用呢。 那么什么是引用呢?引用就是引用引用,这不废话嘛。...= 1; // 正确,1 int &rb1 = i * 2; // 错误,i * 2是rb1位引用 int &&rrb2 = i * 2; // 正确 const int &c =

82921

C++ 类的不同构造与三种引用

主要是变量、常变量(const变量),包括:常量、匿名对象、函数返回 引用const引用引用 引用类型的变量的核心是其可以修改自己对应的内存空间到别的变量(修改this)不是简单的拷贝备份...引用时在类型定义的右边加上&符合的引用变量,如 int a = 1; int & b = a; b = 5;//a == 5 true 引用的变量会直接引用赋值变量,代表相同对象,但是不能引用...,这样就会调用拷贝构造函数去复制 const引用就是通过const限定,允许引用引用,当是引用时,其会调用构造函数,生成一个临时变量存储,再去引用这个临时变量,这是为了避免直接使用普通变量存储时...,但是有时候我们传入的可能是,也可能是,所以当使用泛型的引用来接收时,会自动根据入还是,来自动转化为使用引用还是引用,这种泛型引用也因此被叫为万能引用。...,val解释引用 int a = 1; forwardValue(a);//传入,val解释引用 } 但是因为val是具名变量,是,所以无论解释为何种引用,process

2.3K10

吃透这些内容,c++ 不再难学

const int a = 1; int * const pa = &a; 熟悉的同学一眼就能看出:int * const pa 声明的 pa 是个常量,它指向的内容 int 不是常量 const...int&& b = getValue(); // 一个引用的定义与初始化 根据以下规则可以判断表达式返回的是还是。...:返回的表达式有: 返回引用的函数返回 赋值表达式 下标表达式 dereference 表达式 ++ -- 前缀 :返回的表达式有: 返回引用类型的函数返回 算数表达式 关系表达式...位运算 后缀 ++ -- 其中: 引用可以引用 引用const 引用 可以引用 是持久的,是临时的。...引用。 c++ 在资源管理上有 move assign 的操作,即如果把赋值给其他对象,可以把里的资源 move 到新的对象里,这样防止进行资源的申请与释放。

1.4K30

C++11『引用 ‖ 完美转发 ‖ 新增类功能 ‖ 可变参数模板』

引用 比 指针 好用得多 而我们之前使用的所有引用都称为 引用,主要用于引用各种 变量,如果想引用 常量,需要使用 const 修饰 // 引用 int main() { int a = 10...&& ra = move(a); return 0; } 其中,诸如 「变量 / 数组元素 / 解引用后的指针」 等,在表达式结束后仍然存在、并且可以被取地址的称为 常量 / 临时对象...资源 起别名,当 引用 引用 时,是直接指向 资源,从而对 进行操作;当 引用 引用 时,则是先将 常量 等即将被销毁的临时资源 “转移” 到特定位置,然后指向该位置中的 资源...防止编译器直接将 拷贝构造 优化为 直接构造 首先是测试 C++11 之前的结果(没有 引用) 可以看到这里发生了 3 次 深拷贝 行为,其中一次 str 拷贝构造,一次 str + '...非常合理,首先要明白 是无法被取地址的, 引用 是将 中的资源转存到一块特定的空间中,这也就意味着 引用 后的,必定是一个 (拥有空间,可取地址),只有为 才可以对其进行修改等操作

37250

【C++】C++11 引用和移动语义

一、引用 在 C++11 之前,我们把数据分为常量和变量,而在 C++11 之后,我们将数据分为是一个表示数据的表达式 (如变量名或解引用的指针),我们可以对取地址,也可以对赋值...三、引用引用的比较 引用不能直接引用,但是 const 引用可以引用,因为 const 引用也是只读的,权限可以平移: int main() { // 引用只能引用...引用的提出就是为了补足引用存在的这些短板的。...: 这里关键的点需要注意: 函数的形参的类型都是 T&& x,不是 const T&& x,这是因为最终在 thj::string 类中我们需要将 x 的资源转移给别人,这就要求 x 必须是可修改的...万能引用是一个函数模板,且函数的形参类型引用;对于这样的函数模板,编译器能够自动根据实参的类型 – / const / / const ,自动推演实例化出不同的形参类型分别为 引用

66910

终于弄明白了万能引用引用的区别

,因为指涉到常量引用允许绑定到一个常量型别得形参 */ }; /** 以上得到两个结: 1,如果想取得对某个对象执行移动操作得能力,则不用将其声明为常量,因为针对常量执行得移动操作会变成复制操作...两种含义: 1, 引用,仅仅会绑定到,识别出可移动对象 2,万能引用,可以是引用 T&,也可以是引用, 也可以绑定到 const对象或 volatile对象或两者对象 */ //引用...如下是错误的,一个引用不能绑定一个 std::vector v; f(v); //2 //const修饰,也不是万能引用 //2 //const修饰,也不是万能引用 template...//常量引用既可以操作,也可以操作 rhs // //引用必须立即进行初始化操作,且只能使用进行初始化 // lhs += rhs; // return...name的实参是个,那么 T 就被被推导引用,所以,如果传递 //给 logAndAdd的是个 int,则 T 就会被推导 int&。

1.8K10

C++进阶:C++11(列表初始化、引用与移动构造移动赋值、可变参数模版...Args、lambda表达式、function包装器)

引用就是给引用,给取别名 也是一个表示数据的表达式,如:字面常量、表达式返回,函数返回(这不能是引用返回)等等,可以出现在赋值符号的右边,但是不能出现出现在赋值符号的左边,...是一个临时的、无法被修改的,因此在传返回时,编译器会将该临时对象隐式地添加 const 修饰符,使其成为一个常量对象 3.2引用引用 我们之前使用的引用都是引用,那么现在引用就是...部分传返回的问题(局部对象):在函数返回一个临时对象时,如果返回类型是一个对象不是引用或指针,会导致拷贝构造函数被调用,产生额外的开销。...,不是引用传递。...当万能引用绑定到一个时,它被推导引用;当绑定到一个时,它被推导引用。这样,万能引用可以根据传入的参数的类别来保持其原有的类型。

6800

Chapter 5: Rvalue References, Move Semantics, PF

通用引用引用或者引用,可以绑定到或者,也可以绑定到constconst对象,volatile或volatile对象上,甚至是即const又volatile对象上。...f(T&& param); Widget W; f(w); // 传递,引用 f(std::move(w)); // 传递,引用 类型推导是通用引用的必要条件,但不是充分条件...,因为通用引用可以识别引用 w.setName(n); 如果通过指定引用引用函数来代替通用引用,那么这种做法会使得手写重载函数数量因为函数参数数量呈指数增加 std::move...编码机制是:当传递的参数是一个时,模板参数被推导引用;当传递的参数是一个时,模板参数被推到一个引用。...//C++标准规定:const类型的引用不能绑定到bit域上 //因为没有办法寻址 fwd(h.totalLength); //bit域参数传递的可行方式只有:按传递,或者加上const修饰的引用

5.1K40
领券