Why can't I compare addresses of template classes?

S

Sean J. Fraley

This code illustrates what I'm confused about:

template<typename T>
class foo
{
public:
template<typename U>
void
fooFunction(const foo<U>& x)
{
if(this != &x) //<=== where the problem apparently is.
cout << "yipee!!\n";
}
};

int main()
{
foo<int> x;
foo<float> y;

x.fooFunction(y); // instantiated from here.

return EXIT_SUCCESS;
}

testingg.cpp:38: error: comparison between distinct pointer types
`foo<int>*' and `const foo<float>*' lacks a cast

Why can't I compare the addresses of the two class instances? I'm not
dereferencing the pointers, I'm just making sure that the instance passed
as a parameter to fooFunction is not the same instance that fooFuntion is
being called on.

Is this something that is supposed to happen, or is this just a compiler
issue(gcc 3.3.3).

Thank you
Sean J. Fraley
 
L

Leor Zolman

This code illustrates what I'm confused about:

template<typename T>
class foo
{
public:
template<typename U>
void
fooFunction(const foo<U>& x)
{
if(this != &x) //<=== where the problem apparently is.
cout << "yipee!!\n";
}
};

int main()
{
foo<int> x;
foo<float> y;

If x and y were the same type, it would work. Neither C++ nor C allow you
to indiscriminately compare pointers to different types.

Wouldn't be prudent.

An alternate approach: have two fooFunctions, one taking a const foo &
where you'd do the test, and another taking anything else where the test
wouldn't even be necessary.
-leor
 
S

Sean J. Fraley

Leor said:
If x and y were the same type, it would work. Neither C++ nor C allow you
to indiscriminately compare pointers to different types.

Wouldn't be prudent.

An alternate approach: have two fooFunctions, one taking a const foo &
where you'd do the test, and another taking anything else where the test
wouldn't even be necessary.
-leor

OK.

Just out of curiosity, why is it not a good idea in situations where the
pointer isn't dereferenced. I can't see the harm in comparing if two
pointers point to the same address in memory.

Sean
 
J

John Harrison

Sean J. Fraley said:
OK.

Just out of curiosity, why is it not a good idea in situations where the
pointer isn't dereferenced. I can't see the harm in comparing if two
pointers point to the same address in memory.

Type safety? Normally it would be a mistake, so the compiler flags it as
such.

Another approach would be to cast your pointers to void*, then you could
compare them.

john
 
L

Leor Zolman

Another approach would be to cast your pointers to void*, then you could
compare them.

Yes, of course. For some reason I assumed the OP didn't want to have to
cast, and answered in that context. Looking back on the original post, I
see there was no such preference expressed, so now we have two viable
approaches.

Somewhere in the back of my mind is a niggling concern over the case when
multiple inheritance is in use, and we have pointers to different sub-parts
of an object involved in the comparison. I'm really, really hoping the OP
is not intending to use MI, but if he is, then we should probably pursue a
clarification of if/when either of the two techniques presented might fail
under such circumstances. I have a headache right now and hope it is a
non-issue ;-)
-leor
 
U

Uwe Schnitker

Sean J. Fraley said:
OK.

Just out of curiosity, why is it not a good idea in situations where the
pointer isn't dereferenced. I can't see the harm in comparing if two
pointers point to the same address in memory.

The problem is that pointer comparison is not meant to be a question about
memory addresses, but about object identity. In C, both questions are
essentially equivalent, so the distinction is moot.

In C++, with derived classes, the answer to both questions can differ:

If a class has multiple - non-empty - base classes, at least one of the
pointers to the base parts of an object of the derived class must point
to a different address than a pointer to the derived object, but a pointer
comparison yields true in both cases.

If you want a real "memory address comparison", you need to use void pointers.

Example: With

class D : public B1, public B2 { /*stuff*/ };

and

D* dp = new D;

B1* b1p = dp;
B2* b2p = dp;

you get

dp == b1p; // is true

and

dp == b2p; // ist true

even if with

void* dvp = dp;
void* b1vp = b1p;
void* b2vp = b2p;

one of

dvp == b1vp
dvp == b2vp

will yield false.

Note: If you use

void* dvp = dynamic_cast<void*>(dp); // etc. pp.

all three void pointers will point to the same memory address.

Morale: Void pointers point to memory addresses, other pointers point
to objects. This is often essentially the same, but not always.

On a slightly different note: Additionally, pointers to char (or maybe
unsigned/signed char) can be used to point
to "raw memory". This is needed for memory
address calculations, since you can't calculate
with void pointers.

Uwe
 

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

Members online

No members online now.

Forum statistics

Threads
474,169
Messages
2,570,919
Members
47,460
Latest member
eibafima

Latest Threads

Top