Connecting Tech Pros Worldwide Forums | Help | Site Map

template question

Gonçalo Rodrigues
Guest
 
Posts: n/a
#1: Jul 22 '05
Hi all,

Sorry to bother you guys again with a template question but I'm really
trying to understand them and there's some piece of info that I'm
missing. I'm sure I'm being really dumb here so, please bear with me.
I've reduced my problem to the following:

Remark: the example below is just to highlight my problems with
templates. I know very well that there are already ways of doing what
the example tries to do (for example, with the boost library).

So, for the example. I declare the template in a header file like:

#ifndef TEMPLATESHEADER
#define TEMPLATESHEADER

namespace python {

template<typename T>
class IComparable {
public:
//Assumes operator==.
bool operator!=(const T& other) const;
};

//Methods.
template<typename T>
bool IComparable<T>::operator!=(const T& other) const {
return !(*this == other);
}
}

#endif

Now, I try to use the template in the following:

#include <iostream>
#include "object.hpp"
using namespace python;

//Constructor(s).
Object::Object() {}

//Compare operators.
bool Object::operator==(const Object& other) const {
return this == &other;
}

//Simple testing: later, move this into a testobject.cpp.
int main() {
//Force instantiation.
Object obj;
std::cout << "Size of Object is " << sizeof(obj) << "." <<
std::endl;
Object objA;
std::cout << "Compare equal: " << (obj == objA) << "." <<
std::endl;
std::cout << "Compare unequal: " << (obj != objA) << "." <<
std::endl;
}

For completion's sake let me paste the object.hpp header file

#ifndef OBJECTHEADER
#define OBJECTHEADER

#include "templates.hpp"

namespace python {

class Object : public IComparable<Object> {
public:
//Default constructor.
Object();

//Compare operators.
bool operator==(const Object& other) const;

};
}

#endif

When I try to compile this with the free MS .NET c++ compiler I get:

d:\Goncalo\Programming\C++\Python--\include\templates.hpp(17) : error
C2679: bin
ary '==' : no operator found which takes a right-hand operand of type
'const pyt
hon::IComparable<T>' (or there is no acceptable conversion)
with
[
T=python::Object
]
C:\Programas\Microsoft Visual C++ Toolkit
2003\include\xstring(502) : wh
ile compiling class-template member function 'bool
python::IComparable<T>::opera
tor !=(const T) const'
with
[
T=python::Object
]
D:\Goncalo\Programming\C++\Python--\include\object.hpp(12) :
see referen
ce to class template instantiation 'python::IComparable<T>' being
compiled
with
[
T=python::Object
]


Huh? Can anybody enlighten me in what I am doing wrong?

With my best regards,
G. Rodrigues

Rolf Magnus
Guest
 
Posts: n/a
#2: Jul 22 '05

re: template question


Gonçalo Rodrigues wrote:
[color=blue]
> Hi all,
>
> Sorry to bother you guys again with a template question but I'm really
> trying to understand them and there's some piece of info that I'm
> missing. I'm sure I'm being really dumb here so, please bear with me.
> I've reduced my problem to the following:
>
> Remark: the example below is just to highlight my problems with
> templates. I know very well that there are already ways of doing what
> the example tries to do (for example, with the boost library).
>
> So, for the example. I declare the template in a header file like:
>
> #ifndef TEMPLATESHEADER
> #define TEMPLATESHEADER
>
> namespace python {
>
> template<typename T>
> class IComparable {
> public:
> //Assumes operator==.[/color]

It assumes IComparable<T>::operator==.
[color=blue]
> bool operator!=(const T& other) const;
> };
>
> //Methods.
> template<typename T>
> bool IComparable<T>::operator!=(const T& other) const {
> return !(*this == other);
> }
> }
>
> #endif
>
> Now, I try to use the template in the following:
>
> #include <iostream>
> #include "object.hpp"
> using namespace python;
>
> //Constructor(s).
> Object::Object() {}
>
> //Compare operators.
> bool Object::operator==(const Object& other) const {
> return this == &other;
> }[/color]

Here, you have Object::operator==. But your IComparable operator!=
assumes an operator in IComparable itself, not in the derived class.

Gonçalo Rodrigues
Guest
 
Posts: n/a
#3: Jul 22 '05

re: template question


On Fri, 16 Jul 2004 00:50:32 +0200, Rolf Magnus <ramagnus@t-online.de>
wrote:
[color=blue]
>Gonçalo Rodrigues wrote:
>[color=green]
>> Hi all,
>>
>> Sorry to bother you guys again with a template question but I'm really
>> trying to understand them and there's some piece of info that I'm
>> missing. I'm sure I'm being really dumb here so, please bear with me.
>> I've reduced my problem to the following:
>>
>> Remark: the example below is just to highlight my problems with
>> templates. I know very well that there are already ways of doing what
>> the example tries to do (for example, with the boost library).
>>
>> So, for the example. I declare the template in a header file like:
>>
>> #ifndef TEMPLATESHEADER
>> #define TEMPLATESHEADER
>>
>> namespace python {
>>
>> template<typename T>
>> class IComparable {
>> public:
>> //Assumes operator==.[/color]
>
>It assumes IComparable<T>::operator==.
>[color=green]
>> bool operator!=(const T& other) const;
>> };
>>
>> //Methods.
>> template<typename T>
>> bool IComparable<T>::operator!=(const T& other) const {
>> return !(*this == other);
>> }
>> }
>>
>> #endif
>>
>> Now, I try to use the template in the following:
>>
>> #include <iostream>
>> #include "object.hpp"
>> using namespace python;
>>
>> //Constructor(s).
>> Object::Object() {}
>>
>> //Compare operators.
>> bool Object::operator==(const Object& other) const {
>> return this == &other;
>> }[/color]
>
>Here, you have Object::operator==. But your IComparable operator!=
>assumes an operator in IComparable itself, not in the derived class.[/color]

In my ignorance if the signature in the template is

bool IComparable<T>::operator!=(const T& other) const;

Then it assumes a reference to a T object. If I wanted a reference to
a IComparable<T> (as seems to be really what I am doing) then I would
write

bool IComparable<T>::operator!=(const IComparable<T>& other) const;

But it looks that I'm wrong. So how would I write
IComparable<T>::operator!= to assume the operator in the derived
class?

TIA, with my best regards,
G. Rodrigues

Rolf Magnus
Guest
 
Posts: n/a
#4: Jul 22 '05

re: template question


Gonçalo Rodrigues wrote:
[color=blue]
> On Fri, 16 Jul 2004 00:50:32 +0200, Rolf Magnus <ramagnus@t-online.de>
> wrote:
>[color=green]
>>Gonçalo Rodrigues wrote:
>>[color=darkred]
>>> Hi all,
>>>
>>> Sorry to bother you guys again with a template question but I'm
>>> really trying to understand them and there's some piece of info that
>>> I'm missing. I'm sure I'm being really dumb here so, please bear
>>> with me. I've reduced my problem to the following:
>>>
>>> Remark: the example below is just to highlight my problems with
>>> templates. I know very well that there are already ways of doing
>>> what the example tries to do (for example, with the boost library).
>>>
>>> So, for the example. I declare the template in a header file like:
>>>
>>> #ifndef TEMPLATESHEADER
>>> #define TEMPLATESHEADER
>>>
>>> namespace python {
>>>
>>> template<typename T>
>>> class IComparable {
>>> public:
>>> //Assumes operator==.[/color]
>>
>>It assumes IComparable<T>::operator==.
>>[color=darkred]
>>> bool operator!=(const T& other) const;
>>> };
>>>
>>> //Methods.
>>> template<typename T>
>>> bool IComparable<T>::operator!=(const T& other) const {
>>> return !(*this == other);
>>> }
>>> }
>>>
>>> #endif
>>>
>>> Now, I try to use the template in the following:
>>>
>>> #include <iostream>
>>> #include "object.hpp"
>>> using namespace python;
>>>
>>> //Constructor(s).
>>> Object::Object() {}
>>>
>>> //Compare operators.
>>> bool Object::operator==(const Object& other) const {
>>> return this == &other;
>>> }[/color]
>>
>>Here, you have Object::operator==. But your IComparable operator!=
>>assumes an operator in IComparable itself, not in the derived class.[/color]
>
> In my ignorance if the signature in the template is
>
> bool IComparable<T>::operator!=(const T& other) const;
>
> Then it assumes a reference to a T object. If I wanted a reference to
> a IComparable<T> (as seems to be really what I am doing) then I would
> write
>
> bool IComparable<T>::operator!=(const IComparable<T>& other) const;
>
> But it looks that I'm wrong.[/color]

The problem is the operator== that you are trying to use.

return !(*this == other);

Means the same as:

return ! this->operator==(other);

and 'this' is of type IComparable<T>*, not of type T*. Therefore the
compiler is searching for IComparable<T>::operator== and not for
T::operator==.
[color=blue]
> So how would I write
> IComparable<T>::operator!= to assume the operator in the derived
> class?[/color]

You could do a conversion:

return ! *static_cast<T*>(this) == other;

Ali Cehreli
Guest
 
Posts: n/a
#5: Jul 22 '05

re: template question


On Thu, 15 Jul 2004 16:05:41 -0700, Gonçalo Rodrigues wrote:
[color=blue]
> On Fri, 16 Jul 2004 00:50:32 +0200, Rolf Magnus <ramagnus@t-online.de>
> wrote:
>[color=green]
>>Gonçalo Rodrigues wrote:
>>[/color][/color]
[color=blue][color=green][color=darkred]
>>> namespace python {
>>>
>>> template<typename T>
>>> class IComparable {
>>> public:
>>> //Assumes operator==.[/color]
>>
>>It assumes IComparable<T>::operator==.
>>[color=darkred]
>>> bool operator!=(const T& other) const;
>>> };
>>>
>>> //Methods.
>>> template<typename T>
>>> bool IComparable<T>::operator!=(const T& other) const {
>>> return !(*this == other);
>>> }
>>> }[/color][/color][/color]
[color=blue]
> So how would I write
> IComparable<T>::operator!= to assume the operator in the derived class?[/color]

Try this:

template<typename T>
bool IComparable<T>::operator!=(const T& other) const {
return !(static_cast<const T&>(*this) == other);
}

I can't think of any scenario where that static_cast may cause trouble. (?)

Ali
Gonçalo Rodrigues
Guest
 
Posts: n/a
#6: Jul 22 '05

re: template question


On Fri, 16 Jul 2004 01:28:27 +0200, Rolf Magnus <ramagnus@t-online.de>
wrote:

[text snipped]
[color=blue][color=green]
>> In my ignorance if the signature in the template is
>>
>> bool IComparable<T>::operator!=(const T& other) const;
>>
>> Then it assumes a reference to a T object. If I wanted a reference to
>> a IComparable<T> (as seems to be really what I am doing) then I would
>> write
>>
>> bool IComparable<T>::operator!=(const IComparable<T>& other) const;
>>
>> But it looks that I'm wrong.[/color]
>
>The problem is the operator== that you are trying to use.
>
> return !(*this == other);
>
>Means the same as:
>
> return ! this->operator==(other);
>
>and 'this' is of type IComparable<T>*, not of type T*. Therefore the
>compiler is searching for IComparable<T>::operator== and not for
>T::operator==.
>[/color]

Ahhh... I got it now. The this is of type IComparable<T> and not of
type T which I was implicitely assuming.

Thanks a lot!

G. Rodrigues

Closed Thread


Similar C / C++ bytes