发个帖,讨论下右值引用的问题

夹心饼干 2010-03-10 02:28:15
各位大牛有对右值引用认识比较深的,请抛些玉来
我这有疑问,希望帮忙解答下

问题一
struct test_stru
{
test_stru(){}
test_stru(test_stru&& tt)
{
x = tt.x;
y = tt.y;
}
int x;
int y;
};

test_stru test_r_struct() //一般我们都说不要返回局部对象的引用(左值),现在用右值好象没什么问题?
{
test_stru tt;
tt.x = 10;tt.y = 10;
return tt;
}

void test_print_stru(test_stru&& tt)
{
std::cout<<tt.x<<" "<<tt.y<<std::endl;
};

.....
//test_stru&& f = test_r_struct();
//test_print_stru(f); //这样用是错误的,cannot convert parameter 1 from 'test_stru' to 'test_stru &&'
难道定义的右值引用f不能直接传给函数?还是编译器自动的把它退化成了一个普通的右值变量?

test_print_stru(test_r_struct());//这样OK

原来左值引用做行惨的时候会自动拷贝一份副本,现在用右值引用好了是不用了吧?

问题二: std::move 的问题
std::move 是把一个对象的资源和空间销毁但是保存其存储数据的那部分内存,并返回一个右值引用
看到有人写了这样的代码
std::vector<int>&& test_refer_vec()
{
std::vector<int> vec;
for (int i=1; i<10; ++i)
{
vec.push_back(i);
}
return std::move(vec);
}

返回这样的右值引用有意义吗?vec的资源已经没了,出来的右值也没数据了,难道仅仅是为了提高return时销毁vec的效率?
我对std::move的理解可能不正确,有懂的也帮忙讲讲
...全文
202 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
wade_2003 2010-04-20
  • 打赏
  • 举报
回复
学习学习。
yang6zhen8 2010-04-20
  • 打赏
  • 举报
回复
你对左值、右值及引用,3个概念还是不太清楚。
void test_print_stru(test_stru&& tt),你这个函数的参数是一个右值参数。
这个错误“cannot convert parameter 1 from 'test_stru' to 'test_stru &&'”,可以理解成一个右值参数不能用一个左值来作为输入参数。
你定义的test_stru&& f是一个右值引用,其实f还是左值。
左值是一个引用一段连续存储空间的表达式。而右值是无名的数据,例如函数的返回值一般说来就是右值。
T tmp(moves(a)); 为什么可以,因为moves(a)的返回值就是右值,当然可以。
夹心饼干 2010-03-11
  • 打赏
  • 举报
回复
个人认为右值引用不能做为函数的实参传递,但这个例子好象又可以,哪位大牛给讲讲
test_stru&& f = test_r_struct();
test_print_stru(f); 这是最开始提出的一个问题,右值引用不能做实参
template <class T> 
T&& moves(T&& a)
{
return a;
}
template <class T> void swaps(T& a, T& b)
{
T tmp(moves(a)); 为什么moves返回的是一个右值引用,在这里可以做实参呢?
a = moves(b);
b = moves(tmp);
}
夹心饼干 2010-03-10
  • 打赏
  • 举报
回复
其实在5楼的例子很好改了
std::vector<int> test_refer_vec()
{
std::vector<int> vec;
for (int i=1; i<10; ++i)
{
vec.push_back(i);
}
return std::move(vec);
}
..............
std::vector<int>&& tt = test_refer_vec();
夹心饼干 2010-03-10
  • 打赏
  • 举报
回复
引用 12 楼 akirya 的回复:
引用 8 楼 stormlk1983 的回复:引用 5 楼 stormlk1983 的回复: std::vector <int>&& test_refer_vec() { std::vector <int> vec; for (int i=1; i <10; ++i) { vec.push_back(i); } return std::move(vec); } ........................... std::vector <int>&& vecs = test_refer_vec();//测试发现vecs里面是空的,问下难道std::move不是这样用的吗?把vec的资源移出来? 这个问题akirya 可以帮忙回答下吗?用你写的那个测试程序确实可以,而且std;;move也确实没问题
我觉得你对右值引用没理解对

右值引用是 &&类型的参数去引用临时变量。


非常感谢,我明白你说的意思了
  • 打赏
  • 举报
回复
引用 8 楼 stormlk1983 的回复:
引用 5 楼 stormlk1983 的回复:
std::vector <int>&& test_refer_vec()
{
std::vector <int> vec;
for (int i=1; i <10; ++i)
{
vec.push_back(i);
}
return std::move(vec);
}
...........................
std::vector <int>&& vecs = test_refer_vec();//测试发现vecs里面是空的,问下难道std::move不是这样用的吗?把vec的资源移出来?
这个问题akirya 可以帮忙回答下吗?用你写的那个测试程序确实可以,而且std;;move也确实没问题

我觉得你对右值引用没理解对

右值引用是 &&类型的参数去引用临时变量。
夹心饼干 2010-03-10
  • 打赏
  • 举报
回复
引用 10 楼 yyg990441 的回复:
LZ,我想问下,你是在什么环境编译的?可以支持C++0x可能出的一些标准?我也想搞个玩玩~~~~还有,这些右值引用等等规则在标准出来之前你是从哪里看到的呢?

我用的是VS2010 RC,2010从开始的beta版就已经支持了
yyg990441 2010-03-10
  • 打赏
  • 举报
回复
LZ,我想问下,你是在什么环境编译的?可以支持C++0x可能出的一些标准?我也想搞个玩玩~~~~还有,这些右值引用等等规则在标准出来之前你是从哪里看到的呢?
Yofoo 2010-03-10
  • 打赏
  • 举报
回复
引用其实就是指针, 只是语法区别而已
夹心饼干 2010-03-10
  • 打赏
  • 举报
回复
引用 5 楼 stormlk1983 的回复:
std::vector <int>&& test_refer_vec()
{
std::vector <int> vec;
for (int i=1; i <10; ++i)
{
vec.push_back(i);
}
return std::move(vec);
}
...........................
std::vector <int>&& vecs = test_refer_vec();//测试发现vecs里面是空的,问下难道std::move不是这样用的吗?把vec的资源移出来?

这个问题akirya 可以帮忙回答下吗?用你写的那个测试程序确实可以,而且std;;move也确实没问题
cattycat 2010-03-10
  • 打赏
  • 举报
回复
看来得区分什么是左值和右值了。
第一个例子test_stru& f = test_r_struct();
f引用的是临时对象,是右值,当作为test_print_stru参数就不行了,参数需要引用左值,传递f当参数就是引用右值,应该不行了。
我没看过c++0x,不知道这么理解对不。
  • 打赏
  • 举报
回复
以前写的

#include<stdio.h>
#include<utility>
using namespace std;
struct test
{
int n;
test():n(1)
{
puts( "test::test" );
}
~test()
{
puts( "test::~test" );
}
};
//*
test && operator+( const test& l, test && r)
{
r.n += l.n;
return move( r );
}//*/
test operator+( const test& l , const test& r)
{
test x;
x.n = l.n + r.n;
return x;
}
int main()
{
test a;
test b = a + test() + test() + test();
printf("%d\n" , b.n );
}

比较 注释掉test && operator+( const test& l, test && r)和不注释就能看出效率的差别了。
夹心饼干 2010-03-10
  • 打赏
  • 举报
回复
std::vector<int>&& test_refer_vec()
{
std::vector<int> vec;
for (int i=1; i<10; ++i)
{
vec.push_back(i);
}
return std::move(vec);
}
...........................
std::vector<int>&& vecs = test_refer_vec();//测试发现vecs里面是空的,问下难道std::move不是这样用的吗?把vec的资源移出来?
pengzhixi 2010-03-10
  • 打赏
  • 举报
回复
右值引用得看下次标准了。
夹心饼干 2010-03-10
  • 打赏
  • 举报
回复
引用 1 楼 yyg990441 的回复:
1.
test_stru& f = test_r_struct();
这里就有问题:
test_r_struct()返回的右值应该用
const test_stru& f = test_r_struct();来应用比较好,这样防止修改他
所以
void test_print_stru(test_stru& tt)应该改为
void test_print_stru(const test_stru& tt);

那么第一题楼主的所有写法就都正常了

1楼说的是,我那个是漏了,我的本意是test_stru&& f = test_r_struct();的,写的时候漏了~~~

我不是想知道写法是否正常,通过编译很容易,我希望各位谈谈各自对右值引用的理解
test_stru operator= (test_stru&& tt)
{
this->x = tt.x;
this->y = tt.y;
return *this;
}

比如这个,在copy对象的时候原来的左值引用效率肯定要高的
yyg990441 2010-03-10
  • 打赏
  • 举报
回复
我错了~~~~原来是C++ 0x的东西~~~~
yyg990441 2010-03-10
  • 打赏
  • 举报
回复
1.
test_stru& f = test_r_struct();
这里就有问题:
test_r_struct()返回的右值应该用
const test_stru& f = test_r_struct();来应用比较好,这样防止修改他
所以
void test_print_stru(test_stru& tt)应该改为
void test_print_stru(const test_stru& tt);

那么第一题楼主的所有写法就都正常了

64,642

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧