Re: template syntax to destinguish pointer and objects..?
..rhavin grobert <clqrq@yahoo.de> wrote:
On 2 Jul., 20:49, "Igor Tandetnik" <itandet...@mvps.org> wrote:
.rhavin grobert <cl...@yahoo.de> wrote:
You haven't asked about this, but I'm going to comment anyway. I
assume critical_enter() and critical_leave() are entering and
leaving a critical section, and the goal is to have the container
thread-safe (which is usually misguided, but I won't concentrate on
that). However, you return a reference to an element inside the
vector, and access to this reference is not in any way protected.
This reference may become invalid as soon as the function returns,
when another thread adds an element and the vector has to grow and
reallocate its memory.
if that funtion is called, you either dont need the return or use fact
that critical_enter() and critical_leave() ar public functions, eg:
MyVec.critical_enter();
whatever = MyVec[10];
MyVec.critical_leave();
If you require such explicit calls anyway, why not require them around
add(), too? At which point you can take critical section out of CQVector
and make synchronization the responsibility of the client, where it
belongs.
As your code is written, simply calling add() simultaneously from two
threads (and ignoring any return value) may corrupt m_vec.
You don't need to do anything special - just don't call it. If you
never call a method of a template, it is never instantiated.
I dont call it!
Ah, I see. The function is declared virtual. Virtual functions get
instantiated even if never called. Does it have to be virtual?
You also have a similar problem with
I _ID(T const& t) const {return t.ID();};
which doesn't compile when t is in fact a pointer. It is called from
find_id which is also declared virtual and hence instantiated even
though not called.
What you are looking for is partial template specialization. It goes
like this:
// General template, used by default
template <class T>
class Vector {
void add(const T& t) { printf("1"); }
};
// Partial specialization, used when T is a pointer
template <class T>
class Vector<T*> {
void add(T*) { printf("2"); }
};
Vector<int> v1; v1.add(1); // prints 1
Vector<int*> v2; v2.add(NULL); // prints 2
You can also do partial specialization of template members:
template <class T>
class Vector {
void add(const T&);
};
// general implementation
template <class T>
void Vector<T>::add(const T&) {
}
// implementation for when T is a pointer
template <class T>
void Vector<T*>::add(const T*&) {
}
Unfortunately, if I recall correctly, VC6 doesn't support partial
specialization.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925