473,394 Members | 1,811 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Accelerated C++ exercise 9.2

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?
Jun 27 '08 #1
8 1823
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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '08 #2
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.

--
Umut
Jun 27 '08 #3
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. 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
Jun 27 '08 #4
On Tue, 20 May 2008 10:13:46 -0400, Victor Bazarov wrote:
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?
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
Jun 27 '08 #5
utab wrote:
On Tue, 20 May 2008 10:13:46 -0400, Victor Bazarov wrote:
>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? 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);
This is the problem to tackle.
Really?
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.
>
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
Jun 27 '08 #6
On Tue, 20 May 2008 10:46:38 -0400, Victor Bazarov wrote:
utab wrote:
>On Tue, 20 May 2008 10:13:46 -0400, Victor Bazarov wrote:
>>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
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);
>This is the problem to tackle.

Really?
>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.

>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
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
Jun 27 '08 #7
utab <um********@gmail.comwrote in
news:g0**********@news.albasani.net:
>
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
Jun 27 '08 #8
On May 20, 5:32*pm, Joe Greer <jgr...@doubletake.comwrote:
utab <umut.ta...@gmail.comwrote innews:g0**********@news.albasani.net:
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 :))
Jul 2 '08 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Martin | last post by:
I am reading through Koenig and Moo's "Accelerated C++" and attempting the exercises. Are there any sample solutions somewhere? It's all very well me doing a solution, which seems to work, but for...
3
by: Frankie Montenegro | last post by:
Hi everyone, I must say that, even though I think that Accelerated C++ by Koenig and Moo is an awesome text, the wording of exercises is very poor. I spend half the time just trying to figure...
14
by: Pete | last post by:
Is anyone familiar with this book? Exercise 6-1 of Accelerated C++ asks us to reimplement the frame() and hcat() operations using iterators. I've posted my answers below, but I'm wondering if...
1
by: utab | last post by:
Hi there, I have been reading Accelerated C++ by Andrew Koenig which is an excellent way of learning C++ from even the first pages by using the standard library. One drawback is that no...
3
by: utab | last post by:
Exercise 5.10 from Accelerated C++ by Andrew Koenig Palindromes are words that are spelled the same right to left as left to right. Write a program to find all the palindromes in a dictionary....
8
by: utab | last post by:
Dear all, in a container example, this question is asked in exercises in Accelerated C++ page 154, 8.8? why dont we use (begin+end)/2 instead of begin + (end - begin) / 2 is that someting related...
10
by: Xernoth | last post by:
Hi, This is my first post here, so please be gentle. I've been studying c+ + by mostly using the book Accelerated C++ by Andrew Koenig and Barbara E. Moo. So far, I've been picking things up...
0
by: Lambda | last post by:
I'm trying to complete all the exercises of Accelerated C++. I'm not sure what does the exercise 5-5 mean. And how about 5-9? Thanks
0
by: Lambda | last post by:
It's from the Accelerated C++ exercise 8-1 The old version is based on pointer to function: double analysis(const std::vector<Student_info>& students, double analysis_grade(const Student_info&...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.