C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

const member functions in classes derived from templates.

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
srgama@gmail.com
Guest





PostPosted: Mon Apr 18, 2005 3:11 pm    Post subject: const member functions in classes derived from templates. Reply with quote



Gentlepeople,
I do not understand the interaction between templates and const
member functions(and arguments) as shown in the simplified example
program below.

Any help with explaining why this happens is much appreciated.

thanks,
-sr

//____________________________________________________________
template<int size>
class A {
public:
A() {};
virtual ~A() {};
int GetSize(void) { return size; }
};

class B : public A<1> {
public:
B(): A<1>() {}
virtual ~B() {}

// Implementation A: This compiles fine.
bool operator==(B& rhs) {
return (GetSize()==rhs.GetSize());
}

// Implementation B: This gives compile errors
bool operator==(const B& rhs) const {
return (GetSize()==rhs.GetSize());
}
/*
* ______________________________________________________________
* g++ test_const.cpp
* test_const.cpp: In member function `bool B::operator==(const B&)
* const':
* test_const.cpp:21: passing `const B' as `this' argument of `int
* A<size>::GetSize() [with int size = 1]' discards qualifiers
* test_const.cpp:21: passing `const B' as `this' argument of `int
* A<size>::GetSize() [with int size = 1]' discards qualifiers
*
* ______________________________________________________________
* cl /EHsc test_const.cpp
* Microsoft (R) 32-bit C/C++ Optimizing Compiler
* Version 14.00.40607.16 for 80x86
*
* test_const.cpp
* test_const.cpp(21) : error C2662: 'A<size>::GetSize' :
* cannot convert 'this' pointer from 'const B' to 'A<size> &'
* with
* [
* size=1
* ]
* Conversion loses qualifiers
* test_const.cpp(21) : error C2662: 'A<size>::GetSize' :
* cannot convert 'this' pointer from 'const B' to 'A<size> &'
* with
* [
* size=1
* ]
* Conversion loses qualifiers
* ______________________________________________________________
*
* The errors only occur with a base class access. I am however
* unsure as to why. Would appreciate any help with gaining an
* understanding. -sr
*/
};

int main(void) { return 0;}


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Victor Bazarov
Guest





PostPosted: Tue Apr 19, 2005 10:00 pm    Post subject: Re: const member functions in classes derived from templates Reply with quote



[email]srgama (AT) gmail (DOT) com[/email] wrote:
Quote:
Gentlepeople,
I do not understand the interaction between templates and const
member functions(and arguments) as shown in the simplified example
program below.

Any help with explaining why this happens is much appreciated.

thanks,
-sr

//____________________________________________________________
template<int size
class A {
public:
A() {};
virtual ~A() {};
int GetSize(void) { return size; }
};

class B : public A<1> {
public:
B(): A<1>() {}
virtual ~B() {}

// Implementation A: This compiles fine.
bool operator==(B& rhs) {
return (GetSize()==rhs.GetSize());
}

// Implementation B: This gives compile errors
bool operator==(const B& rhs) const {
return (GetSize()==rhs.GetSize());

Since this expression requires a call to the base class, and that would
require converting 'this' to 'A*' and 'rhs' to 'A&', and since such
conversions while exist, do not cast away constness, both 'this' and
'rhs' get converted to 'A const*' and 'A const&', respectively. After
that the attempt to call a function that is non-const (GetSize() is not
declared 'const') fails.

This has nothing to do with templates. Just declare your A::GetSise()
function 'const':

class A {
...
int GetSize() const { return size; }

and everything is going to be fine.

Quote:
} [...]

V

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Allan W
Guest





PostPosted: Tue Apr 19, 2005 10:12 pm    Post subject: Re: const member functions in classes derived from templates Reply with quote



[email]srgama (AT) gmail (DOT) com[/email] wrote:
Quote:
I do not understand the interaction between templates and const
member functions(and arguments) as shown in the simplified example
program below.

Good job simplifying your program. You gave just enough detail to
show the problem without posting your entire project.

The problem is "const correctness," not templates. I have
converted class A into a simple class to make the real problem
more clear.

Quote:
class A {
public:
A() {};
virtual ~A() {};
int GetSize(void) { return 1; }

/**
Note that GetSize is a *NON-const* function. You cannot call it
on a const object. (It could be const -- it doesn't modify
anything -- but it isn't declared as const.)
A a1;
const A a2;
std::cout << a1.GetSize(); // OK
std::cout << a2.GetSize(); // Error: GetSize() isn't const!
**/


Quote:
};

class B : public A {
public:
B(): A() {}
virtual ~B() {}

// Implementation A: This compiles fine.
bool operator==(B& rhs) {
return (GetSize()==rhs.GetSize());
}

/**
Note that this version is a *NON-const* function. That's okay;
nothing you're doing inside the function requires const. You
can't call this on a const B object, though.
**/

Quote:
// Implementation B: This gives compile errors
bool operator==(const B& rhs) const {
return (GetSize()==rhs.GetSize());
}

/**
This version is a *CONST* function. You CAN call it on a const
B object. But you're trying to call GetSize(). As far as the
compiler knows, GetSize() alters the A sub-object -- you can't
do that in a const function.
**/

Quote:
};


So the solution is to make GetSize() into a const function:

//______________________________________________________________
template public:
A() {};
virtual ~A() {};
int GetSize(void) const { return size; }
};

class B : public A<1> {
public:
B(): A<1>() {}
virtual ~B() {}

bool operator==(const B& rhs) const {
return (GetSize()==rhs.GetSize()); // Okay now
}
};


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Markus Moll
Guest





PostPosted: Tue Apr 19, 2005 10:27 pm    Post subject: Re: const member functions in classes derived from templates Reply with quote

Hello

[email]srgama (AT) gmail (DOT) com[/email] wrote:

Quote:
I do not understand the interaction between templates and const
member functions(and arguments) as shown in the simplified example
program below.

There is none. BTW there is no const member function either.

Quote:
Any help with explaining why this happens is much appreciated.

int GetSize(void) { return size; }

because this should be "int GetSize(void) const { return size; }".
It has nothing to do with templates. You simply attempted to call a
non-const member function through a const reference.

Markus


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Ahti Legonkov
Guest





PostPosted: Tue Apr 19, 2005 10:30 pm    Post subject: Re: const member functions in classes derived from templates Reply with quote

[email]srgama (AT) gmail (DOT) com[/email] wrote:
Quote:
I do not understand the interaction between templates and const
member functions(and arguments) as shown in the simplified example
program below.

Any help with explaining why this happens is much appreciated.

[code snipped]


That's why:
http://www.parashift.com/c++-faq-lite/const-correctness.html

--
Ahti Legonkov
leg zero at hot dot ee


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Nevin :-] Liber
Guest





PostPosted: Tue Apr 19, 2005 10:31 pm    Post subject: Re: const member functions in classes derived from templates Reply with quote

In article <1113834146.980598.43460 (AT) l41g2000cwc (DOT) googlegroups.com>,
[email]srgama (AT) gmail (DOT) com[/email] wrote:

Quote:
Gentlepeople,
I do not understand the interaction between templates and const
member functions(and arguments) as shown in the simplified example
program below.

Any help with explaining why this happens is much appreciated.

Templates and inheritance are orthogonal to the issue of const member
functions. Here is a real simplified example:

class C
{
public:
int GetSize() { return 0; }

// Does not compile
bool operator==(const C& rhs) const
{
return GetSize() == rhs.GetSize();
}
};

Basically, the issue is that const member functions treat all
(non-mutable non-static) member variables as const, and can only call
(static or) const member functions.

operator==(), being a const member function, cannot call GetSize(),
which is a non-const member function.

Regards,
Nevin "Smile" Liber

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Daniel Krügler (ne Spange
Guest





PostPosted: Wed Apr 20, 2005 6:10 am    Post subject: Re: const member functions in classes derived from templates Reply with quote

Hello "srgama",

[email]srgama (AT) gmail (DOT) com[/email] schrieb:

Quote:
Gentlepeople,
I do not understand the interaction between templates and const
member functions(and arguments) as shown in the simplified example
program below.


Your problem is not related to templates, see below.

Quote:
//____________________________________________________________
template<int size
class A {
public:
A() {};
virtual ~A() {};
int GetSize(void) { return size; }

This is a non-const member function. It means that

A a.GetSize();

is a valid while

A<SomeType> const a; // Note: a is **immutable**!
a.GetSize();

is **not**.

You could simplify things by removing templatability and compare

class A2 {
public:
A2() {};
virtual ~A2() {};
int GetSize(void) { return 0; }
}

Here we have

A2 a; // Note: a is mutable!
a.GetSize(); // OK


A2 const a2; // Note: a2 is **immutable**!
a.GetSize(); // ERROR



Quote:
};

class B : public A<1> {
public:
B(): A<1>() {}
virtual ~B() {}

// Implementation A: This compiles fine.
bool operator==(B& rhs) {
return (GetSize()==rhs.GetSize());
}

It compiles fine, because

- operator== is a **mutable** member function
- Its argument is B& and thus a **mutable** object

So you are allowed to call the mutable GetSize() function on *this and
on rhs.

Quote:
// Implementation B: This gives compile errors
bool operator==(const B& rhs) const {
return (GetSize()==rhs.GetSize());
}

It does not (and should not) compile, because

- operator== is an **immutable** member function (as it should be!)
- Its argument is const B& and thus an **immutable** object (as it
should be!)
- but you try to call a mutable member function (namely GetSize) for
*this and
rhs, which are both immutable objects.

This teaches us: Take care of const-correctness!

Since GetSize() obviously is a "read-only" member function and does not
change the internal state of A or B, the correct declaration would be:

bool GetSize() const;

instead of

bool GetSize();

Greetings from Bremen,

Daniel Krügler



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Junker
Guest





PostPosted: Wed Apr 20, 2005 9:07 am    Post subject: Re: const member functions in classes derived from templates Reply with quote

[email]srgama (AT) gmail (DOT) com[/email] wrote in message news:<1113834146.980598.43460 (AT) l41g2000cwc (DOT) googlegroups.com>...
Quote:
Gentlepeople,
I do not understand the interaction between templates and const
member functions(and arguments) as shown in the simplified example
program below.

Any help with explaining why this happens is much appreciated.

thanks,
-sr

//____________________________________________________________
template<int size
class A {
public:
A() {};
virtual ~A() {};
int GetSize(void) { return size; }
};

class B : public A<1> {
public:
B(): A<1>() {}
virtual ~B() {}

// Implementation A: This compiles fine.
bool operator==(B& rhs) {
return (GetSize()==rhs.GetSize());
}

// Implementation B: This gives compile errors
bool operator==(const B& rhs) const {
return (GetSize()==rhs.GetSize());
}
/*
* ______________________________________________________________
* g++ test_const.cpp
* test_const.cpp: In member function `bool B::operator==(const B&)
* const':
* test_const.cpp:21: passing `const B' as `this' argument of `int
* A<size>::GetSize() [with int size = 1]' discards qualifiers
* test_const.cpp:21: passing `const B' as `this' argument of `int
* A<size>::GetSize() [with int size = 1]' discards qualifiers
*
* ______________________________________________________________
* cl /EHsc test_const.cpp
* Microsoft (R) 32-bit C/C++ Optimizing Compiler
* Version 14.00.40607.16 for 80x86
*
* test_const.cpp
* test_const.cpp(21) : error C2662: 'A<size>::GetSize' :
* cannot convert 'this' pointer from 'const B' to 'A<size> &'
* with
* [
* size=1
* ]
* Conversion loses qualifiers
* test_const.cpp(21) : error C2662: 'A<size>::GetSize' :
* cannot convert 'this' pointer from 'const B' to 'A<size> &'
* with
* [
* size=1
* ]
* Conversion loses qualifiers
* ______________________________________________________________
*
* The errors only occur with a base class access. I am however
* unsure as to why. Would appreciate any help with gaining an
* understanding. -sr
*/
};

int main(void) { return 0;}

The GetSize() function declared in the base class is not a const
member function. It is an error to call a non-const member function
from a const member function even in the absence of templates. If you
change the declaration of the A to the following: -

template<int size>
class A {
public:
A() {};
virtual ~A() {};
int GetSize(void) const { return size; }
};

Both Implementation A and Implementation B should compile.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
simont
Guest





PostPosted: Wed Apr 20, 2005 9:14 am    Post subject: Re: const member functions in classes derived from templates Reply with quote

[email]srgama (AT) gmail (DOT) com[/email] wrote:
Quote:
Gentlepeople,
I do not understand the interaction between templates and const
member functions(and arguments) as shown in the simplified example
program below.

Any help with explaining why this happens is much appreciated.

It doesn't look like an interaction at all to me, it just looks like
you're calling a non-const method on a const object.

Quote:

thanks,
-sr

//____________________________________________________________
template<int size
class A {
public:
A() {};
virtual ~A() {};
int GetSize(void) { return size; }
};

class B : public A<1> {
public:
B(): A<1>() {}
virtual ~B() {}

// Implementation A: This compiles fine.
bool operator==(B& rhs) {
return (GetSize()==rhs.GetSize());
}

OK, so you're calling the non-const A<1>::GetSize() method on two
objects, rhs and *this.

Quote:
// Implementation B: This gives compile errors
bool operator==(const B& rhs) const {
return (GetSize()==rhs.GetSize());
}

Now you're calling the same non-const method on two const objects,
which isn't allowed. This isn't usually allowed, though, so why assume
it is because A is a template?

Try const-qualifying A<size>::GetSize, or adding a const overload.
Alternatively, make it static, since it doesn't use any instance data.

If it could be static, of course, it will be the same for all instances
of B, and operator== will always return true. I assume this is an
artefact of the stripped-down example, though?


Simon.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Roger Martinez
Guest





PostPosted: Wed Apr 20, 2005 9:21 am    Post subject: Re: const member functions in classes derived from templates Reply with quote

It is complaining about GetSize() not being const.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Nicola Musatti
Guest





PostPosted: Wed Apr 20, 2005 9:21 am    Post subject: Re: const member functions in classes derived from templates Reply with quote


[email]srgama (AT) gmail (DOT) com[/email] wrote:
Quote:
Gentlepeople,
I do not understand the interaction between templates and const
member functions(and arguments) as shown in the simplified example
program below.

I don't think templates have anything to do with your problem. It is an
error to call a non const member function from a const member function
of the same class. If you turn your class template A in a non template
class you'll get the same errors.

Cheers,
Nicola Musatti


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Roger Martinez
Guest





PostPosted: Wed Apr 20, 2005 9:22 am    Post subject: Re: const member functions in classes derived from templates Reply with quote

To explain further, when you make rhs a const variable, you are making
a promise that you won't modify the object pointed to by that
reference, however you cannot honour that promise because you are
calling GetSize() on rhs, which isn't a const function. Just make
GetSize() const and the error should go away.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Peter Westhagen
Guest





PostPosted: Wed Apr 20, 2005 9:34 am    Post subject: Re: const member functions in classes derived from templates Reply with quote

I believe this has nothing to do with the template aspect of the
problem. The problem is that your A::GetSize method is not defined
const so it can't be called via a const instance of B.

Try this in A instead:

int GetSize(void) const { return size; }


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.