I haven't worked with c++ in a while, but I just started a project with it. This may not be possible, but Im trying to create a template class with an array that sets its size to the value of a constant which i'm trying to set with the constructor.
This is the code of the constructor:
Tarray(int s): start_size(s){
}
This is the code that sets the array size:
const int start_size;
T this_array[start_size];
This is the entire file:
#ifndef TARRAY_H_
#define TARRAY_H_
template<typename T>
class Tarray {
private:
const int start_size;
T this_array[start_size];
int array_size;
public:
Tarray(int s): start_size(s){
}
~Tarray(){
delete[] this_array;
}
T & operator[](int i){
return this_array[i];
}
};
#endif /* TARRAY_H_ */
These are the errors I get:
..\/template_array/Tarray.h:16:24: error: 'Tarray<T>::start_size' cannot appear in a constant-expression
..\/template_array/Tarray.h:16:34: error: 'new' cannot appear in a constant-expression
..\/template_array/Tarray.h:16:34: error: ISO C++ forbids initialization of member 'this_array' [-fpermissive]
..\/template_array/Tarray.h:16:34: error: making 'this_array' static [-fpermissive]
..\/template_array/Tarray.h: In instantiation of 'Tarray<Person>':
..\Human.cpp:17:24: instantiated from here
..\/template_array/Tarray.h:16:34: error: invalid in-class initialization of static data member of non-integral type 'Person*'
Build error occurred, build is stopped
Time consumed: 343 ms.
The error messages have been changing as I try to tweak the code, but these are the errors from this particular build.
Thanks for any help
Use std::vector instead, and make life simple for yourself. :)
(If you want a fixed-size array, then std::array might be a possibility, I think that's in C++11, if not, then boost probably has an implementation).
If you insist on having that ordinary array syntax, though, as if you were using ye-olde C, then you will need to use a template parameter, such that your template class has two arguments - one for the 'T' it already has now, and another for the array size.
You are making life especially difficult by managing that array yourself - if you feel you have to define a destructor, you really should define the copy constructor in addition to the constructor. (That's called the Rule Of The Big Three, if I recall correctly), instead, rely on RAII and avoid having to ever explicitly call operator delete or delete[] yourself.
The following code does something similar but not using the constructor:
and you can use it like this:
The reason you're getting compiler errors is this line:
This line would make your
Tarray
actually containstart_size
instances ofT
. It wouldn't hold a pointer or reference to these instances - they would be part of same block of memory that contains the Tarray's other instance variables. This would make the class' size depend on start_size, and start_size is not known at compile time. The size of any C++ class must be known at compile time, this isn't possible.There are two ways to solve this:
T
instances on the heap, using array new. This is whatstd::vector
does. Writing such a class and getting it to behave right when it's copied/moved/expanded/etc is difficult and tedious, so I'd recommend just usingstd::vector
instead.i.e.:
This is what std::array (C++11 only) and boost::array do. Again, I'd recommend using one of these instead of writing your own. Unless this is homework, of course...
Lastly, it's worth noting that this is an error:
this_array
wasn't allocated withnew
, so you shouldn'tdelete
it. If the array is part of the class as it is here (rather than being separately heap-allocated and owned by the class), then it will be destroyed along with the rest of the class by default. Callingdelete
is not only unnecessary, it will almost certainly cause a crash.You have to create the array at run time.
Note, for this to work, T must have a default constructor (that is, a constructor that takes no arguments).
std::vector
is precisely the tool for this job: