Reputation: 4953
I'm trying to create a simple template class in c++. I've been trying to compile the following but I only get a compile error. This is the code:
#include <stdlib.h>
#include <stdio.h>
template<int size>
class array {
public:
int len;
int data[size];
array(void) : len(size) {}
virtual ~array(void) {}
};
int main() {
array<3> a;
for (int i=0; i < a.len; ++i) {
a.data[i] = i;
printf("%d\n", a.data[i]);
}
return 0;
}
This is the error g++-4.2.1 is giving me:
Undefined symbols:
"__Unwind_Resume", referenced from:
_main in ccaYob9x.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
If we comment out the line for the destructor then the code compiles as it should and it gives me a list of the number 0, 1, 2.
What my ultimate goal is after understanding how template base classes work is to create specialized template classes. I want to create a multidimensional array but I wish to specialize it for the cases when the dimension is 1, 2, and 3. I mainly want to be able to overload the operator()
for those cases. In any case, using a template class like this saves me the trouble of allocating memory dynamically when the dimensions are 1, 2, and 3. Does someone know how to change the code to allocate memory dynamically? Doing so will require you to define the destructor, which is the problem I'm currently facing.
EDIT:
I'm not familiar with template specialization. Does someone know how to make a specialized template when size=1, 2 and 3 to have static memory for data and by default to have dynamic memory?
EDIT 2:
It seems that I'm having trouble due to my g++ compiler. Does anyone see anything with with this:
g++ -v
Using built-in specs.
Target: i686-apple-darwin10
Configured with: /var/tmp/gcc/gcc-5666.3~6/src/configure --disable-checking --enable- werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple- darwin10 --with-gxx-include-dir=/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Apple Inc. build 5666) (dot 3)
EDIT 3:
There has got to be something wrong with my g++ version. I just tried it with g++4.0 in the same machine and with the macports version g++-mp-4.3 and it works fine. I guess it is time to upgrade to the next version. Thank you for your answers and hints.
Upvotes: 1
Views: 10211
Reputation: 20730
This is not stricly related to the question, but let me give you some int hints about yiour code.
First: decide if you want to use C or C++. Templates are C++, but you are "coding as a C programmer". Not that this is bad by itself, bu it is out out context. (use iostream
, not stdlib.h
and stdio.h
, don't use function(void)
but just function()
).
May be it's not your case, but check also your source doesn't have "C" extension (this may fool the compiler) and use g++ (not gcc) as a command (the library you'll link are different)
Second: pay attention about the use of variables and constant: the inst size
as a template parameter, when instantiated is constant. There in no clue in keeping a len
variable (in your design, the array size cannot be changed): a static const int len = size
is all what you need.
Third: if you really want to test, don't use a single for
loop to assign and read values: this makes you completely blind in case of indexes misuse: instead of a.data[i]
try the wrong a.data[0]
and you'll get exactly the same output. Use a loop to fill the array, followed by another loop to read from it.
Fourth: In C++, scopes are important: keep open and closing braces {} aligned. This may sound pedantic, but saved me soooo many times....
Upvotes: 1
Reputation: 3089
Try this:
template<int size>
class array {
public:
int len;
int *data;
array();
virtual ~array(void);
};
// 1 dimension specialized array
template <>
array<1>::array() : len(1)
{
data = new int;
}
template <>
array<1>::~array()
{
delete data;
}
template <int size>
array<size>::array() : len(size)
{
data = new int[size];
}
template <int size>
array<size>::~array()
{
delete [] data;
}
int main(int, char)
{
array<3> a;
for (int i=0; i < a.len; ++i) {
a.data[i] = i;
printf("%d\n", a.data[i]);
}
array<1> b;
for (int i=0; i < b.len; ++i) {
b.data[i] = i;
printf("%d\n", b.data[i]);
}
return 0;
}
With g++ you will not have compiling errors. You can define specialized operator() for each different array sizes without problems, like constructor and destructor seams.
Upvotes: 3