I can take a T*&
from a T*
. Now I need to store my T*
in a type-erased way, more specifically as a void*
. Can I take a T*&
from a void*
? (knowing, of course, that my void*
does point to T
s)
Example:
#include <iostream>
#include <cstdlib>
#include <numeric>
int main() {
int n = 10;
void* mdbuf = malloc(n*sizeof(double));
double* mdarr = (double*)mdbuf;
std::iota(mdarr,mdarr+n,0.); // initialize the memory with doubles
// solution 1: works but not what I want since I want to refer to the type-erased mdbuf variable
double*& mdarr_ref = mdarr; // ok, now mdarr_ref refers to variable mdarr
// solution 2: does not compile
double*& mdbuf_ref = (double*)mdbuf; // error: cannot bind non-const lvalue reference of type 'double*&' to an rvalue of type 'double*'
// solution 3: compiles and work but I want to be sure this is not out of pure luck: is it undefined behavior?
double*& mdbuf_ref = (double*&)mdbuf; // we would like mdbuf_ref to refer to variable mdbuf. It compiles...
std::iota(mdbuf_ref,mdbuf_ref+n,100.);
for (int i=0; i<n; ++i) {
std::cout << mdbuf_ref[i] << ", "; // ...does what we want in this case... is it valid however?
}
}
Edit: Maybe one way to look at it is the following:
double d;
void* v_ptr = &d;
double* d_ptr = (double*)v_ptr; // (1) valid
double& d_ref = d; // (2) valid
double& d_ref2 = (double&)d; // (3) valid? Should be the same as (2) ?
double*& d_ref3 = (double*&)v_ptr; // (4)
The question is: is (4) valid? If (1) and (3) hold, it is just chaining both, so I expect it to be valid, but I would like some evidence of it