 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
srgama@gmail.com Guest
|
Posted: Mon Apr 18, 2005 3:11 pm Post subject: const member functions in classes derived from templates. |
|
|
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
|
Posted: Tue Apr 19, 2005 10:00 pm Post subject: Re: const member functions in classes derived from templates |
|
|
[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.
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
|
Posted: Tue Apr 19, 2005 10:12 pm Post subject: Re: const member functions in classes derived from templates |
|
|
[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.
**/
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
|
Posted: Tue Apr 19, 2005 10:27 pm Post subject: Re: const member functions in classes derived from templates |
|
|
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
|
Posted: Tue Apr 19, 2005 10:30 pm Post subject: Re: const member functions in classes derived from templates |
|
|
[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
|
Posted: Tue Apr 19, 2005 10:31 pm Post subject: Re: const member functions in classes derived from templates |
|
|
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 " " 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
|
Posted: Wed Apr 20, 2005 6:10 am Post subject: Re: const member functions in classes derived from templates |
|
|
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
|
Posted: Wed Apr 20, 2005 9:07 am Post subject: Re: const member functions in classes derived from templates |
|
|
[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
|
Posted: Wed Apr 20, 2005 9:14 am Post subject: Re: const member functions in classes derived from templates |
|
|
[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
|
Posted: Wed Apr 20, 2005 9:21 am Post subject: Re: const member functions in classes derived from templates |
|
|
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
|
Posted: Wed Apr 20, 2005 9:21 am Post subject: Re: const member functions in classes derived from templates |
|
|
[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
|
Posted: Wed Apr 20, 2005 9:22 am Post subject: Re: const member functions in classes derived from templates |
|
|
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
|
Posted: Wed Apr 20, 2005 9:34 am Post subject: Re: const member functions in classes derived from templates |
|
|
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 |
|
 |
|
|
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
|
|