Domanda

Fondamentalmente quello che voglio fare è, a seconda del qualche variabile, per lanciare un puntatore nullo in un tipo di dati diverso. Per esempio (la variabile 'cast' è solo qualcosa al fine di ottenere il mio punto attraverso):

void* ptr = some data;
int temp = some data;
int i = 0;

...

if(temp == 32)      cast = (uint32*)
else if(temp == 16) cast = (uint16*)
else                cast = (uint8*)

i = someArray[*((cast)ptr)];

C'è qualcosa in C ++ che può fare qualcosa di simile (in quanto non si può effettivamente assegna una variabile di essere solo (Uint32 *) o qualcosa di simile)? Mi scuso se questo non è chiaro, tutto l'aiuto sarebbe molto apprezzato.

È stato utile?

Soluzione

Il modo "corretto":

union MyUnion
{
     uint32 asUint32;
     uint16 asUint16;
     uint8 asUint8;
}

uint32 to_index(int size, MyUnion* ptr) 
{  
    if (size== 32) return ptr->asUint32;  
    if (size== 16) return ptr->asUint16;
    if (size== 8) return ptr->asUint8;  
}

i = someArray[to_index(temp,ptr)]

[aggiornamento: fisso errore di battitura muto]

Altri suggerimenti

Chiaramente, boost::variant è il modo di partire. E ' già memorizza un tipo di tag che rende impossibile per voi di lanciare per il tipo sbagliato, garantendo questo utilizzando l'aiuto del compilatore. Ecco come funziona

typedef boost::variant<uint32_t*, uint16_t*, uint8_t*> v_type;

// this will get a 32bit value, regardless of what is contained. Never overflows
struct PromotingVisitor : boost::static_visitor<uint32_t> {
    template<typename T> uint32_t operator()(T* t) const { return *t; }
};

v_type v(some_ptr); // may be either of the three pointers

// automatically figures out what pointer is stored, calls operator() with
// the correct type, and returns the result as an uint32_t.
int i = someArray[boost::apply_visitor(PromotingVisitor(), v)];

Una soluzione più pulita:

uint32 to_index(int temp, void* ptr) {
  if (temp == 32) return *((uint32*)ptr);
  if (temp == 16) return *((uint16*)ptr);
  if (temp == 8) return *((uint8*)ptr);
  assert(0);
}

i = someArray[to_index(temp,ptr)]

Sembra che forse sei dopo un sindacato, o se si sta utilizzando Visual Studio un _variant_t. O forse typeinfo () sarebbe utile? (Per essere onesti, io non sono molto sicuro di quello che si sta cercando di fare).

Per quanto riguarda il cast, si può lanciare qualsiasi cosa a qualsiasi cosa - questo è ciò che rende C ++ pericolosa (e potente se siete molto attenti)

.

Si noti inoltre che i valori di puntatore sono a 32-bit o 64-bit nella maggior parte delle piattaforme, quindi non si poteva memorizzare un uint64 in un void * su una piattaforma a 32 bit.

Infine, forse questo è ciò che si vuole:

void* p = whatever;

uint32 x = (uint32)p;

o forse

uint32 source = 6;

void* p = &source;

uint32 dest = *((uint32*)p);

void* p =

Se sono stati costretti ad utilizzare un PTR vuoto, e assolutamente bisogno di chiamare [] con diversi tipi:

template <typename cast_to>
inline
int get_int_helper(someArray_t someArray, void* ptr) {
   return someArray[*static_cast<cast_to*>(ptr)];
}

int get_int(someArray_t someArray, void* ptr, int temp) {
   switch ( temp ) {
      case 32: return get_int_helper<uint32>(someArray,ptr);
      case 16: return get_int_helper<uint16>(someArray,ptr);
      default: return get_int_helper<uint8>(someArray,ptr);
   }
}

Tuttavia, come altri hanno fatto notare; ci sono probabilmente migliori / altri modi per farlo. Molto probabilmente, qualunque matrice avete non ha più operatori [], quindi non ha bisogno di diversi tipi. Inoltre, si potrebbero utilizzare boost :: variante di tenere un'unione discriminato dei tipi in modo da non dover passare intorno temp

Sembra che si desidera memorizzare la funzione "cast" che prende un void * e produce un intero senza segno. Quindi, ne fanno una funzione:

std::map<int, boost::function<unsigned(*)(void*)> casts;
template <typename T> unsigned cast(void* v) { return *(T*)v; }
casts[32] = cast<uint32>;
casts[16] = cast<uint16>;
casts[8] = cast<uint8>;
casts[128] = MySpecialCastFromDouble;

void* foo = getFoo();
unsigned bar = casts[16](foo);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top