문제

기본적으로 내가하고 싶은 것은 일부 변수에 따라 공간 포인터를 다른 데이터 유형으로 캐스팅하는 것입니다. 예를 들어 ( 'Cast'변수는 내 요점을 가로 질러 내려 가기위한 것입니다) :

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 ++에는 이와 같은 일을 할 수있는 것이 있습니까 (실제로 변수를 단지 (UINT32*) 또는 비슷한 것으로 할당 할 수 없기 때문에)? 이것이 명확하지 않으면 사과드립니다. 어떤 도움도 대단히 감사하겠습니다.

도움이 되었습니까?

해결책

"올바른"방법 :

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

업데이트 : 고정 멍청한 오타

다른 팁

분명히, boost::variant 갈 길입니다. 그것 이미 타입 태그를 저장하여 잘못된 유형으로 캐스트 할 수 없게 만들어 컴파일러의 도움을 사용하여이를 보장합니다. 작동 방식은 다음과 같습니다

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

청소기 솔루션 :

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

어쩌면 당신이 노조를 쫓거나 Visual Studio a _variant_t를 사용하는 것 같습니다. 아니면 typeinfo ()가 도움이 될까요? (솔직히 말해서, 나는 당신이 무엇을하려고하는지 정확히 잘 모르겠습니다).

캐스트에 관한 한, 당신은 무엇이든 주조 할 수 있습니다. 이것이 C ++를 위험하게 만듭니다 (그리고 정말로 조심하면 강력합니다).

또한 포인터 값은 대부분의 플랫폼에서 32 비트 또는 64 비트이므로 32 비트 플랫폼에서 void*에 UINT64를 저장할 수 없습니다.

마지막으로, 이것은 당신이 원하는 것일 것입니다.

void* p = whatever;

uint32 x = (uint32)p;

아니면 어쩌면

uint32 source = 6;

void* p = &source;

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

void* p =

무효 PTR을 사용하는 데 고정되어 있고 다른 유형으로 []를 호출 해야하는 경우 :

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

그러나 다른 사람들이 지적했듯이; 아마도 더 나은/다른 방법이있을 것입니다. 아마도 당신이 가진 배열에 여러 개의 연산자가 없으므로 []가 있으므로 다른 유형이 필요하지 않습니다. 또한 Boost :: Variant를 사용하여 유형의 차별적 인 결합을 보유하여 온도를 전달할 필요가 없습니다.

무효*를 취하고 서명되지 않은 정수를 생성하는 "캐스트"기능을 저장하는 것 같습니다. 따라서 기능으로 만듭니다.

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);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top