468,110 Members | 1,847 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,110 developers. It's quick & easy.

default value with reference variable

sam
Hi,

I m wondering why I can't declare reference variable for default value
in a function argument variable?

eg.

class A
{
void f(string &str="");
};

This causes compiled time error.

Sam.
Jul 23 '05 #1
10 12552

sam wrote:
Hi,

I m wondering why I can't declare reference variable for default value in a function argument variable?

eg.

class A
{
void f(string &str="");
};

This causes compiled time error.

Sam.


Hi,

You cannot declare a non-const reference to non-lvalue. The "string"
that you are tring to declare doesn't have a l-value for the reference
to get associated with. Hence...

void f(const string& str="");

will work fine in VC++ 6.0

-vs_p...

Jul 23 '05 #2
sam
Achintya wrote:
sam wrote:
Hi,

I m wondering why I can't declare reference variable for default
value
in a function argument variable?

eg.

class A
{
void f(string &str="");
};

This causes compiled time error.

Sam.

Hi,

You cannot declare a non-const reference to non-lvalue. The "string"
that you are tring to declare doesn't have a l-value for the reference
to get associated with. Hence...

void f(const string& str="");

Sorry, I m a bit confused with this. Why const string& works and string&
doesn't?

Sam.
will work fine in VC++ 6.0

-vs_p...

Jul 23 '05 #3

sam wrote:
Achintya wrote:
sam wrote:
Hi,

I m wondering why I can't declare reference variable for default
value
in a function argument variable?

eg.

class A
{
void f(string &str="");
};

This causes compiled time error.

Sam.

Hi,

You cannot declare a non-const reference to non-lvalue. The "string" that you are tring to declare doesn't have a l-value for the reference to get associated with. Hence...

void f(const string& str="");

Sorry, I m a bit confused with this. Why const string& works and

string& doesn't?

Sam.
will work fine in VC++ 6.0

-vs_p...


Yup...C++ compilers have two type of 'types' associated with C++
variables and constants. The two types are l-value and r-value. l-value
is associated with variables and r-value is associated with constants.
For ex:

a = 5; // is ok! but because 'a' is a variable and has a associated
'l'ocation in memory hence it has l-value.
5 = a; // is not OK because '5' is a numerical 'const' and doesn't have
a l-value associated with it but it has a r-value

.....and now in your situation the "" string is a const. hence that
cannot be done.

(For more explanation on l-value and r-value look:
http://cplus.about.com/od/cprogrammi...def_lvalue.htm)

-vs_p...

Jul 23 '05 #4
ben
Reference is supposed to be another name of an object. In order for that
object to have a name it must be an "l-value". So what is l-value? Well, in
the statement below:

int phone_number = 21223345;
string my_address = get_my_new_address("my name is ben");

phone_number and my_address are an l-values (left values); 21223345 and
get_my_new_address("my name is ben") are r-values (right values). A variable
can be bound to either an l-value or an r-value. But as with references,
they can only be bound to an l-value. Why? Simply think that an r-value
doesn't have a name. Consider:

int num = 2;
int& ref_to_num = number; // OK, now ref_to_num is just another name of
num

int& ref_to_oops = 2; // Error, ref_to_oops is just another name
of...er...em...nothing! It can't be done!
ref_to_num = 2; // OK, same as num = 2;

why must have a name? Consider:

fruit& apple = fruit();

Well, if the above example works, then apple will reference to a temporary
object fruit(), which will be destroyed at the end of the statement. And the
subsequent use of apple will be catastrophic!

So a workaround of what you want to do might be:

class A
{
static string default_str;
void f(string& str = default_str); // default_str is an l-value
};

string A::default_str = "";
Regards,
Ben

"sam" <ro**@localhost.com> wrote in message
news:d6***********@news.hgc.com.hk...
Achintya wrote:
sam wrote:
Hi,

I m wondering why I can't declare reference variable for default


value
in a function argument variable?

eg.

class A
{
void f(string &str="");
};

This causes compiled time error.

Sam.

Hi,

You cannot declare a non-const reference to non-lvalue. The "string"
that you are tring to declare doesn't have a l-value for the reference
to get associated with. Hence...

void f(const string& str="");

Sorry, I m a bit confused with this. Why const string& works and string&
doesn't?

Sam.
will work fine in VC++ 6.0

-vs_p...

Jul 23 '05 #5
ben wrote:

why must have a name? Consider:

fruit& apple = fruit();

Well, if the above example works, then apple will reference to a temporary
object fruit(), which will be destroyed at the end of the statement. And the
subsequent use of apple will be catastrophic!


Helpful explanation. But I thought a reference bound to a temporary
causes the lifetime of the temporary to extend to the lifetime of the
reference?
Jul 23 '05 #6
Mark P wrote:
ben wrote:

why must have a name? Consider:

fruit& apple = fruit();

Well, if the above example works, then apple will reference to a
temporary
object fruit(), which will be destroyed at the end of the statement.
And the
subsequent use of apple will be catastrophic!


Helpful explanation. But I thought a reference bound to a temporary
causes the lifetime of the temporary to extend to the lifetime of the
reference?


Yes, but you can only bind a rvalue to a const reference.
The above is invalid.
const fruit& = fruit();
Jul 23 '05 #7
ben
> Helpful explanation. But I thought a reference bound to a temporary
causes the lifetime of the temporary to extend to the lifetime of the
reference?


It is a good idea. Indeed it is what is happening with heap-allocated
objects:

int ref_to_num = *(new int); // heap allocation
ref_to_num = 1; // OK
delete &ref_to_num; // End the life of object referenced by
ref_to_num
ref_to_num = 2; // undefined behavior, probably a crash

But with local (stack allocated) variables, things are a little different.
Object construction and destruction is always affiliated with stack
management. So we have

Fact 1. Temporary object must be popped from the stack.
Fact 2. If an object is popped, it must be properly destroyed (by
calling the destructor).

Consequently, a temporary object must be destroyed before the next
statement. If you want to explicitly management the object's lifetime with a
reference, heap allocate the object.

Regards
Ben
Jul 23 '05 #8
ben
> class A
{
void f(string &str="");
};


Apart from my previous comments, the absence of const implies that the
function is gonna change the content of str. But if so a default value
doesn't make sense at all (making change to default value??) This is the
beauty of C++: if you design something seriously wrong, you get a compiler
error :)

Exactly what do you want to achieve with that code?

Ben
Jul 23 '05 #9
ben wrote:
Consequently, a temporary object must be destroyed before the next
statement.


This is not correct. The compiler must guarantee that temporaries bound
to a const reference exist for the lifetime of the reference.
Jul 23 '05 #10
ben wrote:
Helpful explanation. But I thought a reference bound to a
temporary causes the lifetime of the temporary to extend
to the lifetime of the reference?
It is a good idea. Indeed it is what is happening with
heap-allocated objects:

int ref_to_num = *(new int); // heap allocation
ref_to_num = 1; // OK
delete &ref_to_num; // End the life of object referenced by


Undefined behaviour -- ref_to_num is an automatic int,
you copied the value of it from the int created with (new int)
which has now been leaked.
ref_to_num = 2; // undefined behavior, probably a crash
Fine, actually.

Also, this example (even if you modified it to: int &ref_to_num)
has nothing to do with the original topic (extension of
lifetime of temporaries). *(new int) is not a temporary.
Fact 1. Temporary object must be popped from the stack.
There is no need for a 'stack' of any sort to be present.
So this is not really a fact.
Fact 2. If an object is popped, it must be properly destroyed (by
calling the destructor).
You mean, if an object is deallocated it must be properly
destroyed. Which goes without saying. (Note: this 'fact' is
irrelevant, as temporary objects need not be deallocated,
see 'fact 1').
Consequently, a temporary object must be destroyed before the next
statement.
That doesn't follow from anything you just said.
There would be no contradiction if temporary objects lasted
until the end of the current block, for example.
In fact, that is exactly what happens when the temporary
object gets bound to a reference.
If you want to explicitly management the object's lifetime
with a reference, heap allocate the object.


Deeper and deeper into non-sequitur territory. If you want to
manage the lifetime with a reference.... use a reference!

Heap allocation has different semantics than automatic
allocation, as you have already noted.

Jul 23 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

29 posts views Thread by John Wood | last post: by
4 posts views Thread by Carlos Gomez | last post: by
7 posts views Thread by Justin | last post: by
7 posts views Thread by dotnetnoob | last post: by
10 posts views Thread by Joel | last post: by
74 posts views Thread by Zytan | last post: by
10 posts views Thread by Brad Baker | last post: by
4 posts views Thread by Macneed | last post: by
43 posts views Thread by kenneth | last post: by
1 post views Thread by Solo | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.