Accelerated C++ exercise 9.2

U

utab

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?
 
U

utab

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.
 
U

utab

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?
 
U

utab

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);


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.


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
 
J

Joe Greer

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
 
U

utab

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 :))
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,767
Messages
2,569,571
Members
45,045
Latest member
DRCM

Latest Threads

Top