temporary object and const reference

Z

zade

codes like below:
// [[code begin]]
class Foo{
public:
int i;
Foo& operator=(const Foo&){
return *this;
}
};

void func(Foo&){
}

void test(){
func(Foo() = Foo()); // compile ok
func(Foo()); // compile error
}
// [[code end]]


Foo() generate a temporary object, which is a const reference object in c++. so why func(Foo() = Foo()) compile ok but func(Foo()) compile error.
 
S

Saeed Amrollahi

I

codes like below:

// [[code begin]]

class Foo{

public:

int i;

Foo& operator=(const Foo&){

return *this;

}

};



void func(Foo&){

}



void test(){

func(Foo() = Foo()); // compile ok

func(Foo()); // compile error

}

// [[code end]]





Foo() generate a temporary object, which is a const reference object in c++. so why func(Foo() = Foo()) compile ok but func(Foo()) compile error.

I compiled and ran your program under Visual Studio 2010.
There is no error message.

Regards,
-- Saeed Amrollahi Boyouki
 
Z

zade

在 2012å¹´11月15日星期四UTC+8下åˆ2æ—¶09分35秒,Saeed Amrollahi写é“:
I



codes like below:
// [[code begin]]
class Foo{

int i;
Foo& operator=(const Foo&){
return *this;

void func(Foo&){

void test(){
func(Foo() = Foo()); // compile ok
func(Foo()); // compile error

// [[code end]]
Foo() generate a temporary object, which is a const reference object inc++. so why func(Foo() = Foo()) compile ok but func(Foo()) compile error.



I compiled and ran your program under Visual Studio 2010.

There is no error message.



Regards,

-- Saeed Amrollahi Boyouki

I use GCC 3.4.5
 
C

Clinton Mead

codes like below:

// [[code begin]]

class Foo{

public:

int i;

Foo& operator=(const Foo&){

return *this;

}

};



void func(Foo&){

}



void test(){

func(Foo() = Foo()); // compile ok

func(Foo()); // compile error

}

// [[code end]]





Foo() generate a temporary object, which is a const reference object in c++. so why func(Foo() = Foo()) compile ok but func(Foo()) compile error.

func takes a non-const reference, not a const reference. '=' returns a non-const reference, so you can pass it to func, which takes a non-const reference, but Foo() doesn't return a non-const reference, it's a temporary, which you can only pass to a const reference.

If this seems a bit dodgy that you can pass a "temporary" just by setting it equal to something, then yes, it is. In C++11 you can avoid it by having a separate copy assignment operator for objects which are in the temporary state, but I don't think you can do such a thing in C++03.

Clinton
 
R

red floyd

On 11/14/2012 10:09 PM, Saeed Amrollahi wrote:
'redacted]
I compiled and ran your program under Visual Studio 2010.
There is no error message.


That's a VS2010 "extension". Compile with /Za, for strict ISO compliance,
and you will get the error.
By default, MS will allow an rvalue to bind to a non-const reference
parameter, but this is prohibited by the Standard.
 
S

SG

Am 15.11.2012 06:12, schrieb zade:
codes like below:

struct Foo {};
void func(Foo&){
}

void test(){
func(Foo() = Foo()); // compile ok
func(Foo()); // compile error
}


Foo() generate a temporary object, which is a const reference object in c++. so why func(Foo() = Foo()) compile ok but func(Foo()) compile error.

A temporary object is not a "const reference object". What does that
even mean, "const reference object"? A reference is not an object and an
object is not a reference. Also, there is no "const" involved in Foo().
An expression has a type and a value category. The expression

Foo()

is of type Foo and is an "rvalue". As such you may not bind it to a
non-const lvalue reference. But you can work your way around that in
different ways:

struct Foo {
Foo& lvalue() {return *this;}
};

void sink(Foo&);

int main() {
sink(Foo().lvalue());
}

So, it is not specific to the assignment operator. If you're not
disabling this explicitly, non-static functions can be invoked on
temporaries. This means, at some point the adress of the temporary
object will be "bound" to a this pointer.

C++11 offers a way to turn this off:

struct Foo {
Foo& lvalue() & {return *this;}
// ^
// This is a ref qualifier
};

This makes the member function only applicable on non-const lvalue
objects. (Note: I said "non-const lvalue object" because I don't know
any better how to describe it. Of course, the lvalueness is not a
property of the object but a property of the expression that refers to
that object)

Cheers!
SG
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,710
Latest member
bernietqt

Latest Threads

Top