Connecting Tech Pros Worldwide Forums | Help | Site Map

Accelerated C++ exercise 9.2

utab
Guest
 
Posts: n/a
#1: Jun 27 '08
Dear all,

In a question in the highly recommended book Accelerated C++, it is asked
to change a const function into a plain function. After on the reader is
expected to find which function(s) should change.

The function to change is
original version
std::string name() const { return n; }

And this function is called from a predicate function which is passed to
a sort for vector:
original version
bool compare( const Student_info& x, const Student_info& y)
{
return x.name() < y.name();
}

and somewhere in the code sort is called for vector

sort(vec.begin(),vec.end(),compare)

Turning the name into a plain non-const function requires the change of
the const parameters of the compare function because const objects can
call const member functions. But making this change does not solve my
problem. I am getting an error(which is not that helpful from g++) from
the sort function and compare predicate. If someone wants the whole
code(might be a bit long though), I can paste it but I wanted to ask it
directly from the above explanation.

Can somebody help me to figure this problem out?

Victor Bazarov
Guest
 
Posts: n/a
#2: Jun 27 '08

re: Accelerated C++ exercise 9.2


utab wrote:
Quote:
Dear all,
>
In a question in the highly recommended book Accelerated C++, it is
asked to change a const function into a plain function. After on the
reader is expected to find which function(s) should change.
>
The function to change is
original version
std::string name() const { return n; }
>
And this function is called from a predicate function which is passed
to a sort for vector:
original version
bool compare( const Student_info& x, const Student_info& y)
{
return x.name() < y.name();
}
>
and somewhere in the code sort is called for vector
>
sort(vec.begin(),vec.end(),compare)
>
Turning the name into a plain non-const function requires the change
of the const parameters of the compare function because const objects
can call const member functions. But making this change does not
solve my problem. I am getting an error(which is not that helpful
from g++) from the sort function and compare predicate. If someone
wants the whole code(might be a bit long though), I can paste it but
I wanted to ask it directly from the above explanation.
>
Can somebody help me to figure this problem out?
Here is what you have

struct foo {
int bar() const;
};

Here is what the exercise expects you to implement instead:

int bar(foo const&);

A member function takes a hidden argument - the object for which it
is called (you can either think it's a pointer or a reference, it
doesn't matter, really). A non-member function has to have an open
argument (there is nothing hidden in it).

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


utab
Guest
 
Posts: n/a
#3: Jun 27 '08

re: Accelerated C++ exercise 9.2


On Mon, 19 May 2008 22:11:35 -0400, Victor Bazarov wrote:
Quote:
utab wrote:
Quote:
>Dear all,
>>
>In a question in the highly recommended book Accelerated C++, it is
>asked to change a const function into a plain function. After on the
>reader is expected to find which function(s) should change.
>>
>The function to change is
>original version
>std::string name() const { return n; }
>>
>And this function is called from a predicate function which is passed
>to a sort for vector:
>original version
>bool compare( const Student_info& x, const Student_info& y)
>{
> return x.name() < y.name();
>}
>>
>and somewhere in the code sort is called for vector
>>
>sort(vec.begin(),vec.end(),compare)
>>
>Turning the name into a plain non-const function requires the change
>of the const parameters of the compare function because const objects
>can call const member functions. But making this change does not
>solve my problem. I am getting an error(which is not that helpful
>from g++) from the sort function and compare predicate. If someone
>wants the whole code(might be a bit long though), I can paste it but
>I wanted to ask it directly from the above explanation.
>>
>Can somebody help me to figure this problem out?
>
Here is what you have
>
struct foo {
int bar() const;
};
>
Here is what the exercise expects you to implement instead:
>
int bar(foo const&);
>
A member function takes a hidden argument - the object for which it
is called (you can either think it's a pointer or a reference, it
doesn't matter, really). A non-member function has to have an open
argument (there is nothing hidden in it).
>
V
Thanks for the answer, I tested something simple with this code

#include <cstdlib>
#include <iostream>
#include <list>
#include <sstream>
#include <map>

using namespace std;

struct foo{
foo():a(0){}
foo(int A):a(A) {}
//int bar() const {return a;};
int bar() {return a;};
private:
int a;
};

//void test_function(const foo &f)
void test_function(foo &f)
{
cout << f.bar() << endl;
}

int main()
{
foo fobj(5);
test_function(fobj);
return 0;
}

I commented out the const function and replaced that with a non-const
function. It works as intended but I am still not clear what is the
difference for my original problem. That is conceptually the same(or at
least that is what I think). I am trying to call a non-const member
function from inside a non-member function.

--
Umut
Victor Bazarov
Guest
 
Posts: n/a
#4: Jun 27 '08

re: Accelerated C++ exercise 9.2


utab wrote:
Quote:
On Mon, 19 May 2008 22:11:35 -0400, Victor Bazarov wrote:
>
Quote:
>utab wrote:
Quote:
>>Dear all,
>>>
>>In a question in the highly recommended book Accelerated C++, it is
>>asked to change a const function into a plain function. After on the
>>reader is expected to find which function(s) should change.
>>>
>>The function to change is
>>original version
>>std::string name() const { return n; }
>>>
>>And this function is called from a predicate function which is passed
>>to a sort for vector:
>>original version
>>bool compare( const Student_info& x, const Student_info& y)
>>{
>> return x.name() < y.name();
>>}
>>>
>>and somewhere in the code sort is called for vector
>>>
>>sort(vec.begin(),vec.end(),compare)
>>>
>>Turning the name into a plain non-const function requires the change
>>of the const parameters of the compare function because const objects
>>can call const member functions. But making this change does not
>>solve my problem. I am getting an error(which is not that helpful
>>from g++) from the sort function and compare predicate. If someone
>>wants the whole code(might be a bit long though), I can paste it but
>>I wanted to ask it directly from the above explanation.
>>>
>>Can somebody help me to figure this problem out?
>Here is what you have
>>
> struct foo {
> int bar() const;
> };
>>
>Here is what the exercise expects you to implement instead:
>>
> int bar(foo const&);
>>
>A member function takes a hidden argument - the object for which it
>is called (you can either think it's a pointer or a reference, it
>doesn't matter, really). A non-member function has to have an open
>argument (there is nothing hidden in it).
>>
>V
>
Thanks for the answer, I tested something simple with this code
>
#include <cstdlib>
#include <iostream>
#include <list>
#include <sstream>
#include <map>
>
using namespace std;
>
struct foo{
foo():a(0){}
foo(int A):a(A) {}
//int bar() const {return a;};
int bar() {return a;};
private:
int a;
};
>
//void test_function(const foo &f)
void test_function(foo &f)
{
cout << f.bar() << endl;
}
>
int main()
{
foo fobj(5);
test_function(fobj);
return 0;
}
>
I commented out the const function and replaced that with a non-const
function. It works as intended but I am still not clear what is the
difference for my original problem. That is conceptually the same(or at
least that is what I think). I am trying to call a non-const member
function from inside a non-member function.
Why? What is the relevance to the problem at hand? Your 'compare'
function has two arguments, passed by a reference, both const. Why are
you concentrating on const versus non-const? What are you trying to
accomplish by making your stand-alone function to accept a non-const
object (by reference), when the objects you have to deal with are const?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
utab
Guest
 
Posts: n/a
#5: Jun 27 '08

re: Accelerated C++ exercise 9.2


On Tue, 20 May 2008 10:13:46 -0400, Victor Bazarov wrote:
Quote:
utab wrote:
Quote:
>On Mon, 19 May 2008 22:11:35 -0400, Victor Bazarov wrote:
>>
Quote:
>>utab wrote:
>>>Dear all,
>>>>
>>>In a question in the highly recommended book Accelerated C++, it is
>>>asked to change a const function into a plain function. After on the
>>>reader is expected to find which function(s) should change.
>>>>
>>>The function to change is
>>>original version
>>>std::string name() const { return n; }
>>>>
>>>And this function is called from a predicate function which is passed
>>>to a sort for vector:
>>>original version
>>>bool compare( const Student_info& x, const Student_info& y)
>>>{
>>> return x.name() < y.name();
>>>}
>>>>
>>>and somewhere in the code sort is called for vector
>>>>
>>>sort(vec.begin(),vec.end(),compare)
>>>>
>>>Turning the name into a plain non-const function requires the change
>>>of the const parameters of the compare function because const objects
>>>can call const member functions. But making this change does not
>>>solve my problem. I am getting an error(which is not that helpful
>>>from g++) from the sort function and compare predicate. If someone
>>>wants the whole code(might be a bit long though), I can paste it but
>>>I wanted to ask it directly from the above explanation.
>>>>
>>>Can somebody help me to figure this problem out?
>>Here is what you have
>>>
>> struct foo {
>> int bar() const;
>> };
>>>
>>Here is what the exercise expects you to implement instead:
>>>
>> int bar(foo const&);
>>>
>>A member function takes a hidden argument - the object for which it
>>is called (you can either think it's a pointer or a reference, it
>>doesn't matter, really). A non-member function has to have an open
>>argument (there is nothing hidden in it).
>>>
>>V
>>
>Thanks for the answer, I tested something simple with this code
>>
>#include <cstdlib>
>#include <iostream>
>#include <list>
>#include <sstream>
>#include <map>
>>
>using namespace std;
>>
>struct foo{
> foo():a(0){}
> foo(int A):a(A) {}
> //int bar() const {return a;};
> int bar() {return a;};
> private:
> int a;
>};
>>
>//void test_function(const foo &f)
>void test_function(foo &f)
>{
> cout << f.bar() << endl;
>}
>>
>int main()
>{
> foo fobj(5);
> test_function(fobj);
> return 0;
>}
>>
>I commented out the const function and replaced that with a non-const
>function. It works as intended but I am still not clear what is the
>difference for my original problem. That is conceptually the same(or at
>least that is what I think). I am trying to call a non-const member
>function from inside a non-member function.
>
Why? What is the relevance to the problem at hand? Your 'compare'
function has two arguments, passed by a reference, both const.
I think I am a hard learner, or my english is getting worser ;)
Ok let me go slowly: if I change the name to a normal function. The const
references of the stand alone function can not call this function, right?
This is the problem to tackle.

And when calling the stand alone function, the normal object is converted
to a const by the compiler(I am assuming that the parameters are still
const &), but this signature is not appropriate to call a normal function,
right?

If the second reasoning is right, then changing a const function should
also enforce the update of the const& parameters to normal references. This
was my idea on relevance to the struct example.

Or am I still dicussing sth different?

--
Umut
Victor Bazarov
Guest
 
Posts: n/a
#6: Jun 27 '08

re: Accelerated C++ exercise 9.2


utab wrote:
Quote:
On Tue, 20 May 2008 10:13:46 -0400, Victor Bazarov wrote:
>
Quote:
>utab wrote:
Quote:
>>On Mon, 19 May 2008 22:11:35 -0400, Victor Bazarov wrote:
>>>
>>>utab wrote:
>>>>Dear all,
>>>>>
>>>>In a question in the highly recommended book Accelerated C++, it is
>>>>asked to change a const function into a plain function. After on the
>>>>reader is expected to find which function(s) should change.
>>>>>
>>>>The function to change is
>>>>original version
>>>>std::string name() const { return n; }
>>>>>
>>>>And this function is called from a predicate function which is passed
>>>>to a sort for vector:
>>>>original version
>>>>bool compare( const Student_info& x, const Student_info& y)
>>>>{
>>>> return x.name() < y.name();
>>>>}
>>>>>
>>>>and somewhere in the code sort is called for vector
>>>>>
>>>>sort(vec.begin(),vec.end(),compare)
>>>>>
>>>>Turning the name into a plain non-const function requires the change
>>>>of the const parameters of the compare function because const objects
>>>>can call const member functions. But making this change does not
>>>>solve my problem. I am getting an error(which is not that helpful
>>>>from g++) from the sort function and compare predicate. If someone
>>>>wants the whole code(might be a bit long though), I can paste it but
>>>>I wanted to ask it directly from the above explanation.
>>>>>
>>>>Can somebody help me to figure this problem out?
>>>Here is what you have
>>>>
>>> struct foo {
>>> int bar() const;
>>> };
>>>>
>>>Here is what the exercise expects you to implement instead:
>>>>
>>> int bar(foo const&);
>>>>
>>>A member function takes a hidden argument - the object for which it
>>>is called (you can either think it's a pointer or a reference, it
>>>doesn't matter, really). A non-member function has to have an open
>>>argument (there is nothing hidden in it).
>>>>
>>>V
>>Thanks for the answer, I tested something simple with this code
>>>
>>#include <cstdlib>
>>#include <iostream>
>>#include <list>
>>#include <sstream>
>>#include <map>
>>>
>>using namespace std;
>>>
>>struct foo{
>> foo():a(0){}
>> foo(int A):a(A) {}
>> //int bar() const {return a;};
>> int bar() {return a;};
>> private:
>> int a;
>>};
>>>
>>//void test_function(const foo &f)
>>void test_function(foo &f)
>>{
>> cout << f.bar() << endl;
>>}
>>>
>>int main()
>>{
>> foo fobj(5);
>> test_function(fobj);
>> return 0;
>>}
>>>
>>I commented out the const function and replaced that with a non-const
>>function. It works as intended but I am still not clear what is the
>>difference for my original problem. That is conceptually the same(or at
>>least that is what I think). I am trying to call a non-const member
>>function from inside a non-member function.
>Why? What is the relevance to the problem at hand? Your 'compare'
>function has two arguments, passed by a reference, both const.
>
I think I am a hard learner, or my english is getting worser ;)
Ok let me go slowly: if I change the name to a normal function. The const
references of the stand alone function can not call this function, right?
I don't understand this statement. You have a stand-alone function
'compare'. You have a member function 'name'. If you change 'name' to
be a stand-alone function, why couldn't 'compare' call it? You will, of
course, have to change the code of 'compare' to call the new 'name'
because the syntax of calling a standalone function and a member
function is different.

To call a member 'bar' with a 'foo' object, I write

fooObject.bar();

To call a standalone 'bar' with a 'foo' object I write

bar(fooObject);
Quote:
This is the problem to tackle.
Really?
Quote:
And when calling the stand alone function, the normal object is converted
to a const by the compiler(I am assuming that the parameters are still
const &), but this signature is not appropriate to call a normal function,
right?
Again, I don't understand what you're trying to confirm here. If the
argument of the standalone function is a reference to const, the object
will be converted (or even a temporary may be created) and then the
reference argument will be bound to that object. Not sure how
"appropriate" plays here.
Quote:
>
If the second reasoning is right, then changing a const function should
also enforce the update of the const& parameters to normal references. This
was my idea on relevance to the struct example.
>
Or am I still dicussing sth different?
>
Your 'name' member function is 'const'. If you convert it to a
standalone function, you should probably preserve the limitations
imposed by the "const-ness" of the object, IOW make the argument of the
standalone function 'const' as well. That's a design decision, but it
is an important one. If you don't, if you make the standalone function
to require the object to be non-const, then you won't be able to call
that function from a context where the object is 'const' without a
const_cast (which I actually do not recommend).

Am I being unclear? Please point out what is unclear in my explanation
and I will try to rephrase.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
utab
Guest
 
Posts: n/a
#7: Jun 27 '08

re: Accelerated C++ exercise 9.2


On Tue, 20 May 2008 10:46:38 -0400, Victor Bazarov wrote:
Quote:
utab wrote:
Quote:
>On Tue, 20 May 2008 10:13:46 -0400, Victor Bazarov wrote:
>>
Quote:
>>utab wrote:
>>>On Mon, 19 May 2008 22:11:35 -0400, Victor Bazarov wrote:
>>>>
>>>>utab wrote:
>>>>>Dear all,
>>>>>>
>>>>>In a question in the highly recommended book Accelerated C++, it is
>>>>>asked to change a const function into a plain function. After on the
>>>>>reader is expected to find which function(s) should change.
>>>>>>
>>>>>The function to change is
>>>>>original version
>>>>>std::string name() const { return n; }
>>>>>>
>>>>>And this function is called from a predicate function which is passed
>>>>>to a sort for vector:
>>>>>original version
>>>>>bool compare( const Student_info& x, const Student_info& y)
>>>>>{
>>>>> return x.name() < y.name();
>>>>>}
>>>>>>
>>>>>and somewhere in the code sort is called for vector
>>>>>>
>>>>>sort(vec.begin(),vec.end(),compare)
>>>>>>
>>>>>Turning the name into a plain non-const function requires the change
>>>>>of the const parameters of the compare function because const objects
>>>>>can call const member functions. But making this change does not
>>>>>solve my problem. I am getting an error(which is not that helpful
>>>>>from g++) from the sort function and compare predicate. If someone
>>>>>wants the whole code(might be a bit long though), I can paste it but
>>>>>I wanted to ask it directly from the above explanation.
>>>>>>
>>>>>Can somebody help me to figure this problem out?
>>>>Here is what you have
>>>>>
>>>> struct foo {
>>>> int bar() const;
>>>> };
>>>>>
>>>>Here is what the exercise expects you to implement instead:
>>>>>
>>>> int bar(foo const&);
>>>>>
>>>>A member function takes a hidden argument - the object for which it
>>>>is called (you can either think it's a pointer or a reference, it
>>>>doesn't matter, really). A non-member function has to have an open
>>>>argument (there is nothing hidden in it).
>>>>>
>>>>V
>>>Thanks for the answer, I tested something simple with this code
>>>>
>>>#include <cstdlib>
>>>#include <iostream>
>>>#include <list>
>>>#include <sstream>
>>>#include <map>
>>>>
>>>using namespace std;
>>>>
>>>struct foo{
>>> foo():a(0){}
>>> foo(int A):a(A) {}
>>> //int bar() const {return a;};
>>> int bar() {return a;};
>>> private:
>>> int a;
>>>};
>>>>
>>>//void test_function(const foo &f)
>>>void test_function(foo &f)
>>>{
>>> cout << f.bar() << endl;
>>>}
>>>>
>>>int main()
>>>{
>>> foo fobj(5);
>>> test_function(fobj);
>>> return 0;
>>>}
>>>>
>>>I commented out the const function and replaced that with a non-const
>>>function. It works as intended but I am still not clear what is the
>>>difference for my original problem. That is conceptually the same(or at
>>>least that is what I think). I am trying to call a non-const member
>>>function from inside a non-member function.
>>Why? What is the relevance to the problem at hand? Your 'compare'
>>function has two arguments, passed by a reference, both const.
>>
>I think I am a hard learner, or my english is getting worser ;)
>Ok let me go slowly: if I change the name to a normal function. The const
>references of the stand alone function can not call this function, right?
>
I don't understand this statement. You have a stand-alone function
'compare'. You have a member function 'name'. If you change 'name' to
be a stand-alone function, why couldn't 'compare' call it?
If I understand the meaning of stand alone correctly, it is a function
which is not associated to any object. I am not changing it to become a
stand alone function, I am changing it to become a plain member function,

You will, of
Quote:
course, have to change the code of 'compare' to call the new 'name'
because the syntax of calling a standalone function and a member
function is different.
>
To call a member 'bar' with a 'foo' object, I write
>
fooObject.bar();
>
To call a standalone 'bar' with a 'foo' object I write
>
bar(fooObject);
>
Quote:
>This is the problem to tackle.
>
Really?
>
Quote:
>And when calling the stand alone function, the normal object is
>converted to a const by the compiler(I am assuming that the parameters
>are still const &), but this signature is not appropriate to call a
>normal function, right?
>
Again, I don't understand what you're trying to confirm here. If the
argument of the standalone function is a reference to const, the object
will be converted (or even a temporary may be created) and then the
reference argument will be bound to that object. Not sure how
"appropriate" plays here.
>
>
Quote:
>If the second reasoning is right, then changing a const function should
>also enforce the update of the const& parameters to normal references.
>This was my idea on relevance to the struct example.
>>
>Or am I still dicussing sth different?
>>
>>
Your 'name' member function is 'const'. If you convert it to a
standalone function,
Here as well, I am not converting it to a stand alone function. just to a
plain member function.

you should probably preserve the limitations
Quote:
imposed by the "const-ness" of the object, IOW make the argument of the
standalone function 'const' as well. That's a design decision, but it
is an important one. If you don't, if you make the standalone function
to require the object to be non-const, then you won't be able to call
that function from a context where the object is 'const' without a
const_cast (which I actually do not recommend).
>
Am I being unclear? Please point out what is unclear in my explanation
and I will try to rephrase.
>
V
Maybe I am not clear enough, I do not know if you have time to look at the
code in the pastebin below(or have the codes of the book for a further
check), maybe it will be better for the discussion.

http://pastebin.com/d6e7d589f

Thx

--
Umut
Joe Greer
Guest
 
Posts: n/a
#8: Jun 27 '08

re: Accelerated C++ exercise 9.2


utab <umut.tabak@gmail.comwrote in
news:g0upaj$6lc$3@news.albasani.net:
Quote:
>
If I understand the meaning of stand alone correctly, it is a function
which is not associated to any object. I am not changing it to become
a stand alone function, I am changing it to become a plain member
function,
What do you mean by "plain member function?" Both:

string name() const {}

and

string name() {}

(or whatever other permutations you may want) are plain member functions.
One just declares that it won't modify the object and the compiler tries to
help you maintain that desire. In fact, you can have both in your object
at the same time. One will be invoked if you have a const object and the
other one otherwise. This can lead to confusion, so I would think
carefully about that, but it can be done.

The whole const correctness thing is a design decision which requires code
to be written in certain ways so that the compiler can help you detect
coding problems. Your part of the deal is to write your methods
appropriately to maintain this const correctness. That means that you
don't just remove a const specifier from an accessor method. Doing so
implies not only that your method changes your object (or allows changes to
it), it means that you can no longer call that methods from a const form of
your object. (I am putting assign things like const_cast and mutable for
the moment).

I think you may be worrying about things that shouldn't happen in well
thought out code. There is no reason that the act of fetching the name of
an object, for example, should change it. Furthermore, your user's (even
if it's yourself) would intuitively not expect it to change the object.

joe
utab
Guest
 
Posts: n/a
#9: Jul 2 '08

re: Accelerated C++ exercise 9.2


On May 20, 5:32*pm, Joe Greer <jgr...@doubletake.comwrote:
Quote:
utab <umut.ta...@gmail.comwrote innews:g0upaj$6lc$3@news.albasani.net:
>
>
>
Quote:
If I understand the meaning of stand alone correctly, it is a function
which is not associated to any object. I am not changing it to become
a stand alone function, I am changing it to become a plain member
function,
>
What do you mean by "plain member function?" *Both:
>
* * * * string name() const {}
>
and
>
* * * string name() {}
>
(or whatever other permutations you may want) are plain member functions. *
One just declares that it won't modify the object and the compiler tries to
help you maintain that desire. *In fact, you can have both in your object
at the same time. *One will be invoked if you have a const object and the
other one otherwise. *This can lead to confusion, so I would think
carefully about that, but it can be done.
>
The whole const correctness thing is a design decision which requires code
to be written in certain ways so that the compiler can help you detect
coding problems. *Your part of the deal is to write your methods
appropriately to maintain this const correctness. *That means that you
don't just remove a const specifier from an accessor method. *Doing so
implies not only that your method changes your object (or allows changes to
it), it means that you can no longer call that methods from a const form of
your object. *(I am putting assign things like const_cast and mutable for
the moment).
>
I think you may be worrying about things that shouldn't happen in well
thought out code. *There is no reason that the act of fetching the name of
an object, for example, should change it. *Furthermore, your user's (even
if it's yourself) would intuitively not expect it to change the object.
>
joe
Just solved after moving to another country I started to work again :))
Closed Thread