Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Temporary Object

43 views
Skip to first unread message

Haochen Xie

unread,
May 14, 2013, 9:25:16 PM5/14/13
to
Assuming we have class C defined as:

class C {
public:
int x, y;
C operator++() { ++x, ++y; return *this; }
};

So the following line is legal since C is a user defined type:

++C();

But could any one tell me why the following codes are illegal:

void foo(C &c, int val) {
printf("%d, %d\n", c.x, c.y);
c.x = c.y = val;
printf("%d, %d\n", c.x, c.y);
}
int main() {
foo(C(), 8);
}

When I try to compile it with gcc, the compiler complains:

invalid initialization of non-const reference of type 'C&' from an
rvalue of type 'C'

in passing argument 1 of 'void foo(C&, int)'

Is there any reason to make it invalid? And is there any way to pass a
temporary object to a mutable function without a variable to hold it?

Ian Collins

unread,
May 14, 2013, 9:46:52 PM5/14/13
to
It's invalid because the standard says so!

In most cases, it makes little sense to perform non-const operations on
a temporary object.

--
Ian Collins

Haochen Xie

unread,
May 15, 2013, 1:01:20 AM5/15/13
to
Ian Collins wrote:
>
> It's invalid because the standard says so!
>
> In most cases, it makes little sense to perform non-const operations on
> a temporary object.
>

Yeah, I also think that's the only reason why it's invalid, since you
could actually call a member function on a temporary object and the
function could pass itself as an argument to another function, which
could bypass this restriction (and that shows their should not be
technical difficulty).

Actually I saw this code from Crypto++ User's Guide by denis bider:

// Crypto++
#include "cryptlib.h"

// std
#include <iostream>


void DumpMessage(CryptoPP::BufferedTransformation& bt)
{
using namespace std;

static char const* szHexDigits = "0123456789abcdef";
byte b;
while (bt.AnyRetrievable())
{
if (!bt.Get(b))
throw "Error: AnyRetrievable() returned true, "
"so this shouldn't happen.";

// It is much easier to implement this using HexEncoder;
// however, let's not get into that just yet. The below code
// could do some special kind of processing that is not
// supported by an off-the-shelf Filter class.

cout << szHexDigits[(b >> 4) & 0x0f]
<< szHexDigits[b & 0x0f]
<< ' ';
}
}


// Crypto++
#include "filters.h"

int main()
{
using namespace CryptoPP;

char const* szMessage = "How do you do?";
DumpMessage(StringSource(szMessage, true));
// If we constructed StringSource with 'false' instead
// of 'true',
// StringSource wouldn't call its PumpAll() method on
// construction,
// and no data would be extractable from the StringSource
// object
// until someone called the object's Pump() or PumpAll()
// method.

return 0;
}

That doesn't compile on my compiler, but it's on the tutorial anyway.
Probably the author's compiler does not follow the standard on this issue.

Paavo Helde

unread,
May 15, 2013, 1:56:57 AM5/15/13
to
Haochen Xie <hao...@xie.name> wrote in
news:kmv4r3$pnu$1...@speranza.aioe.org:

> Ian Collins wrote:
>>
>> It's invalid because the standard says so!
>>
>> In most cases, it makes little sense to perform non-const operations
>> on a temporary object.
>>
>
> Yeah, I also think that's the only reason why it's invalid, since you
> could actually call a member function on a temporary object and the
> function could pass itself as an argument to another function, which
> could bypass this restriction (and that shows their should not be
> technical difficulty).

There is no technical difficulty. Binding temporaries to non-const
references is forbidden as a special rule, as it appeared this would create
too many subtle bugs in the code because of automatic conversions. Using a
member function returning the right type of non-const reference does not
involve automatic conversions, so this is considered safe.

Cheers
Paavo
0 new messages