Pergunta

Basicamente o que eu quero fazer é, dependendo da alguma variável, para lançar um ponteiro nulo em um tipo de dados diferente. Por exemplo (a variável 'cast' é apenas algo para conseguir meu ponto de vista):

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)];

Existe alguma coisa em C ++ que pode fazer algo como isso (desde que você não pode realmente atribuir uma variável a ser apenas (uint32 *) ou algo similar)? Peço desculpas se isso não está claro, qualquer ajuda seria muito apreciada.

Foi útil?

Solução

A maneira "correta":

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)]

[update: Corrigido um erro de mudo]

Outras dicas

Claramente, boost::variant é o caminho a ir. É armazena um tipo de tags que faz com que seja impossível para você elenco para o tipo errado, assegurando isso usando a ajuda do compilador. Aqui está como ele funciona

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)];

solução mais limpa A:

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)]

Parece que talvez você é depois de uma união, ou se você estiver usando o Visual Studio um _variant_t. Ou talvez typeinfo () seria útil? (Para ser honesto, eu não tenho certeza exatamente o que você está tentando fazer).

Quanto aos moldes, você pode lançar qualquer coisa para qualquer coisa -. É isso que faz C ++ perigosa (e poderoso se você estiver realmente cuidado)

Além disso, nota que os valores de ponteiro são 32-bit ou 64-bit na maioria das plataformas, para que você não pode armazenar um uint64 em um * vazio em uma plataforma de 32 bits.

Finalmente, talvez este seja o que você quer:

void* p = whatever;

uint32 x = (uint32)p;

ou talvez

uint32 source = 6;

void* p = &source;

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

void* p =

Se você estava bloqueado em usar um ptr vazio, e absolutamente necessário para chamada [] com diferentes tipos:

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);
   }
}

No entanto, como outros apontaram; há provavelmente melhor / outras maneiras de fazê-lo. Muito provavelmente, qualquer matriz que você tem não tem operador múltipla [], por isso não precisa de diferentes tipos. Além disso, você poderia estar usando boost :: variant para realizar uma união discriminada dos tipos para que você não teria que passar em torno de temperatura

Parece que você deseja armazenar a função de "cast" que leva a * vazio e produz um inteiro sem sinal. Assim, torná-lo uma função:

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);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top