lvalue (s) and rvalue (s) | | |
Hello,
void func( const string& ISIN) {
cout << ISIN << endl;
}
int main() {
char bufIsin[31];
char *charIsin = new char[31];
strcpy(bufIsin, "FIRST");
strcpy(charIsin, "SECOND");
func(bufIsin);
func(charIsin);
}
1. The above compiles fine. In both instances, a char * is passed to the
func( ). On the other hand, func( ) recieves a string &. What is the exact
argument passing process? (i.e is the string(char *) ctr invoked? is this
called type promotion?)
2. If the func( )'s signature is void func(string& ISIN) the code does not
compile. Can you explain to me the meaning of the error, please?
~/MyTests $CC Passing_CharBuf_Char\*_to_func_accepting_string.cc
"Passing_CharBuf_Char*_to_func_accepting_string.cc ", line 21: Error: Formal
argument ISIN of type std::basic_string<char,
std::char_traits<char>, std::allocator<char>>& in call to
func(std::basic_string<char, std::char_traits<char>,
std::allocator<char>>&) requires an lvalue.
"Passing_CharBuf_Char*_to_func_accepting_string.cc ", line 22: Error: Formal
argument ISIN of type std::basic_string<char, std::char_traits<char>,
std::allocator<char>>& in call to func(std::basic_string<char,
std::char_traits<char>, std::allocator<char>>&) requires an lvalue.
2 Error(s) detected.
TIA
jimjim | | | | re: lvalue (s) and rvalue (s)
P.S: what happens if the char * is not null terminated and the string(const
char *) ctr is invoked? Does string dim = "hello"; ensure that the "hello"
is terminated? | | | | re: lvalue (s) and rvalue (s)
"jimjim" <netuser@blueyonder.co.uk> schrieb im Newsbeitrag news:WYbVf.41838$wl.15595@text.news.blueyonder.co. uk...[color=blue]
> Hello,
>
> void func( const string& ISIN) {
> cout << ISIN << endl;
> }
>
> int main() {
> char bufIsin[31];
> char *charIsin = new char[31];
> strcpy(bufIsin, "FIRST");
> strcpy(charIsin, "SECOND");
> func(bufIsin);
> func(charIsin);
> }
>
> 1. The above compiles fine. In both instances, a char * is passed to the
> func( ). On the other hand, func( ) recieves a string &. What is the exact
> argument passing process? (i.e is the string(char *) ctr invoked? is this
> called type promotion?)[/color]
The type of func's parameter is "const string&", not just "string&". The compiler will generate a temporary string object, initialize it with the contents of the character array and pass a reference to the temporary object to the function.
[color=blue]
> 2. If the func( )'s signature is void func(string& ISIN) the code does not
> compile. Can you explain to me the meaning of the error, please?[/color]
A reference to a non-const object cannot be bound to a temporary.
HTH
Heinz | | | | re: lvalue (s) and rvalue (s)
>> void func( const string& ISIN) {[color=blue][color=green]
>> cout << ISIN << endl;
>> }
>>
>> int main() {
>> char bufIsin[31];
>> char *charIsin = new char[31];
>> strcpy(bufIsin, "FIRST");
>> strcpy(charIsin, "SECOND");
>> func(bufIsin);
>> func(charIsin);
>> }
>>
>>
>>2. If the func( )'s signature is void func(string& ISIN) the code does not
>> compile. Can you explain to me the meaning of the error, please?[/color][/color]
[color=blue]
>A reference to a non-const object cannot be bound to a temporary.[/color]
Does the compiler require a const argument because changing the state of a
temporary object is practically without any essence?
What does "func(std::basic_string<char, std::char_traits<char>,
std::allocator<char>>&) requires an **lvalue**" mean?
TIA | | | | re: lvalue (s) and rvalue (s)
>The type of func's parameter is "const string&", not just "string&". The[color=blue]
>compiler will generate a temporary string
>object, initialize it with the contents of the character array and pass a
>reference to the temporary object to the function.[/color]
By the way, is the temporary object created on the stack? | | | | re: lvalue (s) and rvalue (s)
jimjim wrote:
[color=blue][color=green][color=darkred]
>>> void func( const string& ISIN) {
>>> cout << ISIN << endl;
>>> }
>>>
>>> int main() {
>>> char bufIsin[31];
>>> char *charIsin = new char[31];
>>> strcpy(bufIsin, "FIRST");
>>> strcpy(charIsin, "SECOND");
>>> func(bufIsin);
>>> func(charIsin);
>>> }
>>>
>>>
>>>2. If the func( )'s signature is void func(string& ISIN) the code does
>>>not
>>> compile. Can you explain to me the meaning of the error, please?[/color][/color]
>[color=green]
>>A reference to a non-const object cannot be bound to a temporary.[/color]
>
> Does the compiler require a const argument because changing the state of a
> temporary object is practically without any essence?[/color]
No. The reasons for that provision are lost to history. In my opinion, it is
just a bug in the language. In my experience, it makes for much hassle
without tangible gain.
Modifying a temporary makes perfect sense: just think of a proxy class; it
undergoes some changes and at the end of its lifetime writes back the
changes to the object from which it was created. Or think of a temporary
stream object:
#include <fstream>
#include <string>
#include <iomanip>
int main ( void ) {
std::fstream ( "/dev/stdout" )
<< std::dec
<< std::string( "hello world!\n" );
}
Now, you may wonder that this compiles as the temporary is clearly modified.
The reason is that the standard does *not* prohibit calling non-const
members on temporaries. That is the reason for std::dec. In comparison, the
following does not compile:
#include <fstream>
#include <string>
#include <iomanip>
int main ( void ) {
std::fstream ( "/dev/stdout" )
<< std::string( "hello world!\n" );
}
If you can find a rational for this, please let me know.
Best
Kai-Uwe Bux
ps.: this is one of my pet peeves. So please excuse the ranting. | | | | re: lvalue (s) and rvalue (s)
"Kai-Uwe Bux" <jkherciueh@gmx.net> skrev i meddelandet
news:e06fla$6m1$1@murdoch.acc.Virginia.EDU...[color=blue]
> jimjim wrote:
>[color=green]
>> Does the compiler require a const argument because changing the
>> state of a
>> temporary object is practically without any essence?[/color]
>
> No. The reasons for that provision are lost to history. In my
> opinion, it is
> just a bug in the language. In my experience, it makes for much
> hassle
> without tangible gain.[/color]
But jimjim is right on the original motivation. The C promotion rules
for built in types is the real "bug".
void inc(float& x)
{ ++x; }
int i = 0;
inc(i);
or even
inc(1.0);
What would happen here, if it was allowed? Nothing!
The parameter would be converted to a float temporary, which is then
incremented.
[color=blue]
>
> Modifying a temporary makes perfect sense: just think of a proxy
> class; it
> undergoes some changes and at the end of its lifetime writes back
> the
> changes to the object from which it was created. Or think of a
> temporary
> stream object:
>
> #include <fstream>
> #include <string>
> #include <iomanip>
>
> int main ( void ) {
> std::fstream ( "/dev/stdout" )
> << std::dec
> << std::string( "hello world!\n" );
> }
>[/color]
On the other hand, *this* is a bug in the language. :-)
Bo Persson | | | | re: lvalue (s) and rvalue (s)
Bo Persson wrote:
[color=blue]
>
> "Kai-Uwe Bux" <jkherciueh@gmx.net> skrev i meddelandet
> news:e06fla$6m1$1@murdoch.acc.Virginia.EDU...[color=green]
>> jimjim wrote:
>>[color=darkred]
>>> Does the compiler require a const argument because changing the
>>> state of a
>>> temporary object is practically without any essence?[/color]
>>
>> No. The reasons for that provision are lost to history. In my
>> opinion, it is
>> just a bug in the language. In my experience, it makes for much
>> hassle
>> without tangible gain.[/color]
>
> But jimjim is right on the original motivation. The C promotion rules
> for built in types is the real "bug".
>
> void inc(float& x)
> { ++x; }
>
> int i = 0;
> inc(i);
>
> or even
>
> inc(1.0);
>
> What would happen here, if it was allowed? Nothing!
>
> The parameter would be converted to a float temporary, which is then
> incremented.
>[/color]
Ok, I agree that inc(i) doing nothing might be surprising. On the other
hand, I would not want it to do the expected thing either: increment i as a
float and then truncate the result (thus overall being just unpredictable
due to rounding).
However, I wonder: is it really the initialization of a non-const reference
from a temporary that causes the problem or the implicit conversion. But I
guess, we agree on that: as you pointed out, the bug lies within the
promotion rules.
[snip]
Best
Kai-Uwe Bux |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,353 network members.
|