can I return by reference to prevent creating temporary value

Started by
3 comments, last by grady 21 years, 5 months ago
I have a class that has some member functions. say for a matrix I have an transpose function that can be used like so: double filldata[] ={ 1, 2, 3,4, 5,6,7,8,9}; mat3 M( filldata ); M.trn( ); this code makes M the transpose of the matrix formed by the filldata. But suppose I want to write the function such that it returns a value, so that I can do things like: double filldata[] ={ 1, 2, 3,4, 5,6,7,8,9}; mat3 A; mat3 M( filldata ); A = M.trn( ); If I define the trn() function like so: mat3 &trn() { //do a transpose on the matrix; return *this; } since I return by reference will that prevent a temporary object from being created when the trn function returns? I know I could define functions that take pointers for arguments and let all my functions return pointers like D3DX math functions so that the return value of a function can be used as an argument to another funcion, but I don''t want people using this library to deal with pointers if they don''t have to; and I''m writing this lib all in C++ so if its possible to avoid, I definently don''t want to do it. thaks in advance for any advice.
----------------------------www.physicsforums.comwww.opengl.org
Advertisement
quote:Original post by grady
since I return by reference will that prevent a temporary object from being created when the trn function returns?
Yes. What you''re doing works fine. But I would never call a function named "trn"
As far as I know, this would only work if you returned *this. In other cases where you construct a value and then return it, you cannot return a &.
However as far as I know GCC and VC (probably, I''m not sure) do Named Return Value Optimization (NRVO). I''m sure GCC does it. Basically if you do something like:

matrix matrix::dosomething() {
matrix m(...);
return m;
}

in quite a lot of cases, the compiler can optimize away the temporary. I''m pretty sure VC does this since VC is ..a very good optimizing compiler.


-----------------------------
Gamedev for learning.
libGDN for putting it all together.
quote:
However as far as I know GCC and VC (probably, I''m not sure) do Named Return Value Optimization (NRVO). I''m sure GCC does it.


gcc3.1 does this for sure, gcc3.0 may. Anyways, from what I understand NRVO just allocates the return variable in the return register, such as eax for x86 asm. I don''t see how this works with values larger than 32-bits though. Anyone are to explain?
The RVO is more complicated than that.

#include <iostream>using namespace std;struct T{	T () { cout << "D"; } // default construction	T (T const&) { cout << "C"; } // copy construction};T f1 () { return T(); }T f2 () { T t; return t; }T f3 () { T t; t = T(); return t; }int main (){	cout << "min D max D = ";	T t1;	cout << endl;	cout << "min D max DC = ";#ifndef __GNUC__	T t2( (T()) ); // to avoid most vexing parse#else // __GNUC__	T t2((0, T())); // to avoid g++ parse bug#endif // __GNUC__	cout << endl;	cout << "min D max DC = ";	T t3 = T();	cout << endl;	cout << "min D max DCC = ";	T t4(f1());	cout << endl;	cout << "min D max DCC = ";	T t5 = f1();	cout << endl;	cout << "min D max DCC = ";	T t6(f2());	cout << endl;	cout << "min D max DCC = ";	T t7 = f2();	cout << endl;	cout << "min DD max DDCC = ";	T t8(f3());	cout << endl;	cout << "min DD max DDCC = ";	T t9 = f3();	cout << endl;}  


g++ will eliminate every single copy construction. I think Intel will too, not sure. VC++ leaves some in.

About the parse bug: To avoid the most vexing parse ((C) Scott Meyers), one should wrap the constructor call in brackets, to force it to be treated as an expression rather than a function pointer declaration. However, g++ has a parse bug, and will halt the compile. The insertion of the "0," forces evaluation as an expression -- thereby fixes the most vexing parse -- but prevents VC++ from performing the RVO properly.

From http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&frame=right&th=a0bc5c8ff07e8a0f&seekm=9fn050%246n4%241%40taliesin.netcom.net.uk#link5


[edited by - DrPizza on November 20, 2002 4:45:10 AM]
char a[99999],*p=a;int main(int c,char**V){char*v=c>0?1[V]:(char*)V;if(c>=0)for(;*v&&93!=*v;){62==*v&&++p||60==*v&&--p||43==*v&&++*p||45==*v&&--*p||44==*v&&(*p=getchar())||46==*v&&putchar(*p)||91==*v&&(*p&&main(0,(char**)(--v+2))||(v=(char*)main(-1,(char**)++v)-1));++v;}else for(c=1;c;c+=(91==*v)-(93==*v),++v);return(int)v;}  /*** drpizza@battleaxe.net ***/

This topic is closed to new replies.

Advertisement