Re: C++ Templates on MS VS C++
coder_lol@yahoo.com wrote:
I put together a quick array template for MS Visual Studio 2003, but I
ran into some trouble. It's been quite a while since I had to roll my
own templates, so I'd appreciate all help.
Example 1
Array<int> *ibuf = new Array<int>(100);
ibuf[0] = 100; //O K
The above is equivalent to:
Array<int>* ibuf = new Array<int>(100); // an array of 100 Array<int>'s
{
const Array<int>& temp(100); // a Array<int> of 100 int's
ibuf[0] = temp; // assign temp to first slot in ibuf
} // destroy temp
But judging your confusion in the following context, I doubt the above
is what you really want to achieve. You might have wanted to write:
Array<int> buff(100); // array of 100 int's
buff[0] = 21;
Example 2
String *sptr = NULL;
Array<String*> *locales = new Array<String*>(50);
locales[0] = sptr; // ERROR, WHY?
Because locales is not an Array. It's a POINTER to Array. And by
convention locales[0] refers to the first Array<String*> object out of
50 you have just created. So basically you are trying to assign an
Array<String*> with a String*. Read on.
(*locales)[0] = sptr; // OK, but WHY ???
The * dereferences locales so the expression (*locale) is an Array, and
hence the [] operator apply.
Example 3 - OK: forward declaration of template class without
including template header.
template<class int8>
class Array;
Example 4 - ERROR: why ??? forward declaration of template class
without including template header.
template<class String*>
class Array;
Example 3 worked. But I suspect that it doesn't work in a way you may
have expected. Basically to forward declare a class template you do:
template <class T>
class C;
Where T is just an identifier to be used like a typename in the template
definition.
So in Example 3, the declaration is valid, you have just substituted T
with int8 and C with Array.
In Example 4, the declaration is invalid. It's because String* is an
identifier followed by a * operator.
Thank-you all!
=== ARRAY TEMPLATE ===
template<class T=int32>
class Array : public Object
{
Although this is ok, I'd strongly recommend you not to give a default
type parameter and not to inherit from Object. So you'd be better off by
using:
template <class T>
class Array{
public:
Array(int32 aSize);
For better portability, consider using std::size_t instead of int32.
(int32 is not a built-in type anyway.) Also, to avoid confusion you had
in Example 1, make the constructor explicit:
explicit Array(std::size_t aSize);
virtual ~Array();
If you drop the inheritance, then virtual destructor is not needed.
int32 length() const;
T& operator[](int32 i);
For const use, also provide:
const T& operator[](std::size_t) const;
T *getData() const;
The above member function is ill-declared. Consider instead:
T* getData();
const T* getData() const;
private:
T *data;
int32 size;
Before you finish the class, make sure you also provide a copy
constructor and an assignment operator:
template <class U>
Array(const Array<U>&);
template <class U>
Array<T>& operator=(const Array<U>&);
};
Regards,
Ben