can I return by reference to prevent creating temporary value
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.
quote:Original post by gradyYes. What you''re doing works fine. But I would never call a function named "trn"
since I return by reference will that prevent a temporary object from being created when the trn function returns?
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.
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.
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]
#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]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement