struct SomeStruct
{
int a;
int b;
};
SomeStruct someFn( int init )
{
SomeStruct ret = { init, init };
//...
return ret;
}
void someFn2( SomeStruct* pStruct )
{
// ..
}
int main( )
{
someFn2( &someFn(32) );
return 0;
}
views:
254answers:
4No, it's not valid.
From 5.2.2/10 [expr.call] "A function call is an lvalue if and only if the result type is a reference.
From 5.3.1/2 [expr.unary.op] "The operand shall be an lvalue or a qualified-id".
someFn(32)
is, therefore, not an lvalue as SomeStruct
is not a reference and you are using it as the operand to &
which requires an lvalue.
$ g++ -Wall -o stuct struct.cc struct.cc: In function ‘int main()’: struct.cc:21: warning: taking address of temporary
You should probably be doing:
int main( )
{
SomeStruct s = someFn(32);
someFn2(&s);
return 0;
}
No it's not.
You can only use & on lvalues. SomeFn(32) is not a lvalue.
Your main should be like this :
int main( )
{
SomeStruct s;
s = someFn(32);
someFn2(&s);
return 0;
}
The usual idiom is to pass a const reference rather than a pointer if your function can accept temporaries.
#include<iostream>
struct SomeStruct {
int a;
int b;
~SomeStruct() {
std::cout << "SomeStruct destroyed" << std::endl;
}
};
SomeStruct someFn ( int init )
{
SomeStruct ret = { init, init };
return ret;
}
void someFn2 ( SomeStruct* pStruct )
{
std::cout << "someFn2 called" << std::endl;
}
void someFn2 ( const SomeStruct& someStruct )
{
std::cout << "someFn2 called" << std::endl;
}
int main( )
{
someFn2 ( &someFn ( 32 ) ); // warning - taking address of temporary
someFn2 ( someFn ( 32 ) ); // no warning - safe in non-broken compilers
return 0;
}
outputs
someFn2 called
SomeStruct destroyed
someFn2 called
SomeStruct destroyed
IIRC, the set of 'non-broken' compilers does not include Visual C++ 2003 or earlier.
An example of this idiom in the stl would be:
string a = "red";
string b = " apple";
string c = a + b;
where the std::string(const std::string&)
constructor is called for c
with the temporary std::string
returned from the call to std::string::operator+
.