Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to find the sizeof(T) when creating a template in C++?

Tags:

c++

templates

I'm trying to build a template that will let me use a resizable array. Is there a way to find the sizeof(T)? I'm using malloc rather than new because I want to use realloc in the function that resizes the array. This is the constructor for my class that is getting errors:

template <class T>
set<T>::set(void) {
arr = malloc(10 * sizeof(T));
numElts = 0;
size = 10;
};

I get the following error message when trying to build:

error C2440: '=' : cannot convert from 'void *' to 'int *'
1>          Conversion from 'void*' to pointer to non-'void' requires an explicit cast
1>          c:\set.cpp(42) : while compiling class template member function 'set<T>::set(void)'
1>          with
1>          [
1>              T=int
1>          ]

In the main function I'm calling it with:

set<int> *set1 = new set<int>();

From the research I've done, it looks like the compiler has no way of knowing what to use for sizeof(T), so it can't compile. How else would I go about this?

like image 819
Dom12 Avatar asked Nov 29 '22 03:11

Dom12


2 Answers

malloc returns a void*, and while C allowed incompatible pointers to be assigned, C++ does not. You need to cast to T* the result of malloc assuming arr is defined as T*.

arr = static_cast< T* >( malloc(10 * sizeof(T)) );

There is no problem in calling sizeof(T) within a template, as long as T is complete at the point of the instantiation (and int is a fundamental type, its always complete).

like image 142
K-ballo Avatar answered Dec 05 '22 13:12

K-ballo


Of course you can. That's not the reason for the error you're having.

I'm guessing the set::arr member is of type T*. Because you've instantiated your set class with template parameter type int the declaration of that member variable becomes int *arr;. C++, unlike C, does not let you implicitly cast from a void * to another pointer type. So you'll need to cast the result of the malloc call.

arr = static_cast<T *>( malloc( 10 * sizeof(T) ) );

Also, remember that when you're actually inserting elements into the set you need to use placement new to construct the elements into the buffer you've allocated, and then explicitly invoke their destructors when copying / moving / removing them.

like image 20
Praetorian Avatar answered Dec 05 '22 14:12

Praetorian