关于右值引用的一个错误。



实验课上,有同学遇到类似如下代码的错误。

1. 如下代码编译时会出错。

#include <string>

using namespace std;

class Complex{

public:

Complex(float r = 0, float i = 0){

re = r;

im = i;

}

void print(){

cout<<re<<"+"<<im<<endl;

};

private:

float re, im;

};

void f1(Complex &c){

c.print();

}

Complex f2(){

Complex c(1, 2);

return c;

}

int main(){

f1(f2);

return 0;

}

编译结果(MinGW):

||=== Build: Debug in test (compiler: GNU GCC Compiler) ===|

E:\CPPTest\test\main.cpp||In function ‘int main()‘:|

E:\CPPTest\test\main.cpp|25|error: invalid initialization of non-const reference of type ‘Complex&‘ from an rvalue of type ‘Complex (*)()‘|

E:\CPPTest\test\main.cpp|17|error: in passing argument 1 of ‘void f1(Complex&)‘|

||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

2. 出现的错误与右值引用有关系,可以百度“右值引用”,可找到答案。

简单讲,由于临时变量在被赋予新值之前,都会被销毁,此规则可防止修改临时变量的值。

代码改为如下后,编译通过。

#include <iostream>

#include <iomanip>

#include <string>

using namespace std;

class Complex{

public:

Complex(float r = 0, float i = 0){

re = r;

im = i;

}

void print() const{                                 //改为常函数

cout<<re<<"+"<<im<<endl;

};

private:

float re, im;

};

void f1(const Complex &c){                   //改为常引用

c.print();

}

Complex f2(){

Complex c(1, 2);

return c;

}

int main(){

f1(f2());

return 0;

}

时间: 2024-10-11 14:32:56

关于右值引用的一个错误。的相关文章

翻译「C++ Rvalue References Explained」C++右值引用详解 Part3:右值引用

本文为第三部分,目录请参阅概述部分:http://www.cnblogs.com/harrywong/p/4220233.html. 右值引用 如果x是任意类型,那么x&&则被称作一个对x的右值引用(rvalue reference).为了更好区分,原来的引用x&现在也被称作左值引用(lvalue reference). 一个右值引用是一种同原始引用x&的行为非常类似的类型,但是有一些特例.最重要的一个就是当面临方法重载决议的时候,左值倾向于旧式的左值引用,而右值偏向于新的

从4行代码看右值引用

从4行代码看右值引用 概述 右值引用的概念有些读者可能会感到陌生,其实他和C++98/03中的左值引用有些类似,例如,c++98/03中的左值引用是这样的: int i = 0; int& j = i; 这里的int&是对左值进行绑定(但是int&却不能绑定右值),相应的,对右值进行绑定的引用就是右值引用,他的语法是这样的A&&,通过双引号来表示绑定类型为A的右值.通过&&我们就可以很方便的绑定右值了,比如我们可以这样绑定一个右值: int&

c++11的右值引用、移动语义

对于c++11来说移动语义是一个重要的概念,一直以来我对这个概念都似懂非懂.最近翻翻资料感觉突然开窍,因此记下.其实搞懂之后就会发现这个概念很简单,并无什么高深的地方. 先说说右值引用.右值一般指的是表示式中的临时变量,在c++中临时变量在表达式结束后就被销毁了,之后程序就无法再引用这个变量了.但是c++11提供了一个方法,让我们可以引用这个临时变量.这个方法就是所谓的右值引用. 那么右值引用有什么用呢?避免内存copy! 不同于其它语言,在c++里变量是值语义(在JAVA.Python变量是引

【C++11新概念】:右值引用

C语言原始定义:在C语言中表示位于赋值运算符两侧的两个值,左边的就叫左值,右边的就叫右值. 左值: 地址,内存中的具体空间,可以被读写:例如变量 左值指的是如果一个表达式可以引用到某一个对象,并且这个对象是一块内存空间且可以被检查和存储 右值: 数据,例如1,‘哈哈哈哈’ 右值指的是引用了一个存储在某个内存地址里的数据.不能通过引用或指针读写.用户无法控制这个右值. 一个区分左值和右值的方法是:能不能对这个值取地址. return语句: 按照以前C的说法,return语句如果是按值传递的话,re

翻译「C++ Rvalue References Explained」C++右值引用详解 Part1:概述

本文系对「C++ Rvalue References Explained」 该文的翻译,原文作者:Thomas Becker. 该文较详细的解释了C++11右值引用的作用和出现的意义,也同时被Scott Meyers推荐,全文共分11个部分,我将利用业余时间,分别翻译. 受笔者水平所限,可能叙述会出现些许问题,还望多多指正. 部分名词为了保持含义和方便理解,并未翻译成中文,有的在括号内给出了常见的中文翻译. 目录 概述 Move语义 右值引用 强制Move语义 右值引用就是右值吗? Move语义

Google C++ Coding Style:右值引用(Rvalue Reference)

右值引用是一个C++11特性,标记为T&&.GSG中定义:只为移动建构函数(Move constructor)和移动赋值操作(Move assignment)使用右值引用.并且不要使用std::Forward(提供的完美转发特性). C++中右值指表达式结束时就不再存的临时对象.在C++11中,右值分为纯右值(即原始字面量,表达式产生的临时变量等),以及一个将亡值(expiring value, 使用<<深入应用C++11>>中的译法,指的是与右值引用相关的表达式,

win编程实践(5)【c++】- 右值引用

右值引用形式:类型 && a= 被引用的对象. 与左值引用&的区别在于:右值是临时变量, 可理解为右值的引用,右值初始化后临时变量消失. 从实践角度讲,它能够完美解决C++中长久以来为人所诟病的临时对象效率问题.从语言本身讲,它健全了C++中的引用类型在左值右值方面的缺陷.从库设计者的角度讲,它给库设计者又带来了一把利器.从库使用者的角度讲,不动一兵一卒便可以获得"免费的"效率提升- 在标准C++语言中,临时量(术语为右值,因其出现在赋值表达式的右边)可以被传给

Item 24: 区分右值引用和universal引用

本文翻译自<effective modern C++>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 古人曾说事情的真相会让你觉得很自在,但是在适当的情况下,一个良好的谎言同样能解放你.这个Item就是这样一个谎言.但是,因为我们在和软件打交道,所以让我们避开"谎言"这个词,换句话来说:本Item是由"抽象"组成的. 为了声明一个指向T类型的右值引用,你会写T&&.因此我们可以"合理"地假设:如果你在源代

C++11标准之右值引用(rvalue reference)

1.右值引用引入的背景 临时对象的产生和拷贝所带来的效率折损,一直是C++所为人诟病的问题.但是C++标准允许编译器对于临时对象的产生具有完全的自由度,从而发展出了Copy Elision.RVO(包括NRVO)等编译器优化技术,它们可以防止某些情况下临时对象产生和拷贝.下面简单地介绍一下Copy Elision.RVO,对此不感兴趣的可以直接跳过: (1) Copy Elision Copy Elision技术是为了防止某些不必要的临时对象产生和拷贝,例如: struct A { A(int)