Fog Creek Software
Discussion Board




template question

I have a generic template container classTplate for other types,
say the container contains type l, or/and it's subclass instances, can it also contain a pointer to l,
I.E can the container hold both l and l* ? or  do use 2 containers like

Tplate<l> cont1;
Tplate<l*> cont2?
Is there anyway to have I and I* in the same container?

sumit
Tuesday, February 11, 2003

It depends on what you're trying to do. In most situations, the answer is no.

The thing to remember is that templates work by expansion at the time of call. So you could have a template with a set of functions that work on I, and a different set of functions that work on I*. As long as the caller only calls the right set, it should be fine.

However, there's also the question of store-by-value vs store-by-reference semantics. Every item in a vector< T > must be the same size for the vector to work correctly.

In practice, this is very confusing and extremely difficult to get right. With a few more details I might be able to be more helpful.

Chris Tavares
Wednesday, February 12, 2003

No, because I* and I are completely different objects. They have different sizes, construction/destruction semantics and copy methods.

The simplest solution (to what I _think_ you're trying to do), is to just use I*. Make sure you use the same memory management (if any) for all objects in this container. That is, if some are dynamically allocated, then they all should be dynamically allocated (even if this means making copies of automatics).

http://ninjacoder.com/

Shinobi
Wednesday, February 12, 2003

I realize I and I* are not the same size, so there is ambiguity there, but will compilers allow to store them?
As templates are textually expanded,I should think you should think it won't allow as Type T I ans T *I are different.

sumit
Wednesday, February 12, 2003

Again, you haven't given enough information to say.

It is *POSSIBLE* to write a template to do this. However, I don't think it's useful.

All the compiler does is make sure that every time you invoke an operation on type T (whatever T happens to be) that the operation is legal. So, if you have an object of type T named m_myObj, if the template does:

m_myObj->SomeOperation();

Then type T must be one of:

A pointer to an object that has a SomeOperation() method

or

An object that implements operator-> that returns a pointer to an object that has a SomeOperation() method.

So here's a case where you could have either a pointer or a class passed as a template parameter.

Again, we need to know more specifically what you want to do? Just trying to win a bar bet? The answer it yes, it's possible to write a template that will store objects and pointers simultaneously. It's a useless exercise, since it will be extremely complex and very inefficient, but it is possible.

Trying to actually write one? Well, why? What do you want to do?

Also, none of the pre-defined C++ containers (vector< T >, dequeue< T >, list< T >, set< T >, or map< K, T > ) will let you do this. They're written for values of only one type at a time.

Chris Tavares
Wednesday, February 12, 2003

To begin with, the first line of your question is confusing: "I have a generic template container classTplate".  If it's your generic template container, nobody on this board is in any position to tell you how it behaves.  I can tell you how std::vector behaves, but your container must behave differently, otherwise you would just use std::vector.  Therefore, everything that everybody has said (and which I will say) is really just a best guess.

"Is there anyway to have I and I* in the same container": no.  And you wouldn't want to, anyway, because there is nothing you can do with both I and I*, and there would be no way to access them.

What you probably want is a container which holds I by reference (most likely you would instantiate your container on I*), in which case you have to be aware of memory management issues.

But again, these are just best guesses.  You're the only one here who has the information to answer definitively.

Brian
Wednesday, February 12, 2003

Was just curoious what would happen...came across this kind of situation once where the template could store objects and pointers to objects, don't know exactly how it was implemented...but it worked.....

sumit
Wednesday, February 12, 2003

Proof of concept code:  I don't claim it's useful.

#include <vector>
template<class T> class WierdContainer
{
    std::vector<T> m_byVal;
    std::vector<T*> m_byRef;
public:
    void push_back(const T& val){m_byVal.push_back(val);}
    void push_back(T* ref){m_byRef.push_back(ref);}
    void visit(const WierdVisitor<T>& visitor);  /* implementation left out to deter anyone from trying to use it.  I hope that if you know how to implement it, you also know enough not to. */
};

How do you do anything with the contents?  Easy, you just subclass this:

template<class T> class WierdVisitor
{
    virtual void operator()(const T&) const = 0;
    virtual void operator()(const T*) const = 0;
};

There.  A container that holds both T and T*.  Don't ever use it if you like your job.

Brian
Wednesday, February 12, 2003

*  Recent Topics

*  Fog Creek Home