c++pointerscasting

Specify the type of a C++ pointer at runtime (generic pointer)


I am developing a simulation code written entirely in C++ where we use double precision for all computations. Now I want to make it configurable to use single precision if the user wants. The problem is that all our matrices are defined as double so I am wondering if I can have a generic pointer and specify the type at runtime. For instance, let's say our code looks like this:

double *mat = nullptr;
mat = new double[some_size];
// Some operations...
delete[] mat;

No I want to use same variable and not introduce a new one for single precision since this will require lots of modifications in the code. I tried void pointer but the problem is that I cannot use indices to access elements in the matrix:

void *ptr = nullptr;                                                                                                                                                                                                                    
ptr = new complex<double>[10];

for (auto i = 0; i < 10; ++i) {
  ptr[i].real(1.33445);
  ptr[i].imag(443.223);
}

delete[] ptr;

In this case I get the following error:

error: subscript of pointer to incomplete type 'void'

Also I get a warning which says that the void pointer cannot be deleted.

Now my question is:

Is there any possible way (similar to a void pointer) to have a generic pointer and then cast it properly to a specific type at runtime?


Solution

  • A void* is not meant to be used that way. The only good use of a void* is in low level code where we need to pass along the address of a memory location.

    If you must access the object lying at that memory location like in your use of the subscript operator, you must explicitly convert this void* to a T* where T is a complete type.

    This means that you will be doing a whole lot of explicit conversions which is unsafe if you happen to convert to the wrong type. Anyways here is one possible approach:

    void* ptr = nullptr;                                                                                                                                                                                                                    
    ptr = new complex<double>[10];
    
    for (auto i = 0; i < 10; ++i) {
      static_cast<complex<double>*>(ptr)[i].real(1.33445);
      static_cast<complex<double>*>(ptr)[i].imag(443.223);
    }
    
    delete[] static_cast<complex<double>*>(ptr);