-
Analyzing Code
Hi. I am studying Bjarne Stroustrup's book. He gives the following code while explaining references:
Code:
#include<iostream>
#include<vector>
#include<string>
using namespace std;
struct Pair
{
string name;
double val;
};
vector<Pair> pairs;
double& value(const string& s)
{
for(int i=0; i<pairs.size(); i++)
if(s==pairs[i].name)
return pairs[i].val;
Pair p={s, 0};
pairs.push_back(p);
return pairs[pairs.size()-1].val;
}
int main()
{
string buf="aa";
value(buf)++;
string buf2="aa";
value(buf2)++;
for(vector<Pair>::const_iterator p=pairs.begin();
p!=pairs.end (); ++p)
cout<<p->name<<": "<<p->val<< '\n';
cin.get();
return 0;
}
OK. First of all, I notice that if I do this:
Code:
double value(const string& s)
...
I get a compile-time error:
Code:
non-lvalue in increment
He speaks of these lvalues here. I don't follow.
Also, I don't quite understand this:
Code:
...const string& s)
Why is it const? What does this do?
Thanks in advance, Steve
-
>> I get a compile-time error: "non-lvalue in increment"
I don't. However, if you're using Visual Studio 6.0, you will get error C2552 which is a compiler bug.
What compiler are you using? Perhaps it's just too old and defunct.
>> I don't quite understand this: "const string& s"
s is a reference parameter which prevents any overhead due to copy constructor calls. It is also const because it is not the intention of the value() function to actually modify s. Also, the compiler may be able to perform other optimizations since it knows that s will not be modified.
gg
-
Const means that the function being called cannot modify the data being passed, in this case a reference to a constant string. The lvalue refers to a variable which can be assigned to or modified in some way.
value(buf)++;
Above you are trying to increment a return value that is never stored anyway, it would be better if you did:
dValue = value(buf)++;
-
I'm using Dev-C++ 4.9.8.0
As soon as I remove the ampersand, I get that error message which points to:
Thanks, Steve
-
that should be:
dValue = value(buf);
dValue++;
sorry
-
>>Above you are trying to increment a return value that is never stored anyway...
Yes it is. It's stored in an element of the pairs vector.
>>I'm using Dev-C++ 4.9.8.0
Which will compile the code you posted with 0 errors and 0 warnings. Copy and paste the code you posted back into your source file and re-compile.
gg
-
Thanks... but once I remove the ampersand from:
Code:
double& value(const string& s)
...
As in:
Code:
double value(const string& s)
...
I get that error message.
Thanks, Steve
-
Hmmm, never knew you could do that. I am not use to that syntax. Ahhh, I'm with you... It is stored because it is retuning a reference to a double and not a value, implicity a ptr to an element in the array. I like that.
-
Don't remove the ampersand. You're original code posting is correct.
gg
-
Thanks. Yes - I used Mr. Stroustrup's code. I just didn't understand the concept. I'm still not sure I do. What exactly is happening here? I'm not used to seeing a function incremented. Why does it increment with the ampersand, and throw an error without one? ~Steve
-
Here's an attempt at a simple explanation...
When something is passed by reference, that something itself is passed, as opposed to a copy of that something. In your example, a reference to a double is returned from value(). So you can look at as
Code:
(pairs[pairs.size()-1].val)++
because that's what is returned on that particular call to value(). Same thing goes for the value(buf2) call. That's why you end up with the Pair: ["aa", 2] in the vector.
gg
-
Hehe, he never said he got any errors with the code he posted, Codeplug.
He said that he got errors when he removed the ampersand from the original code, which is natural.
-
>> First of all, I notice that if I do this: ...
Reading is fundamental after all.....doh.
gg
-
Thanks
I appreciate it. I'll try my best to learn from and understand this. ~Steve