2012-05-22 5 views
0

"Tiny Template Library"의 변형 유형을 사용하고 있습니다. 내가 네트워크를 통해 이러한 유형의 객체를 보내고 "재구성"할 때 그것은 포인터 텟 분명하다 "방어 적이기"을 사용하여ttl :: variant, placement new

template< TTL_TPARAMS_DEF(TTL_MAX_TYPELIST_PARAMS, empty_type) > 
struct variant 
{ 
    typedef variant this_t; 
    typedef meta::typelist< TTL_ARGS(TTL_MAX_TYPELIST_PARAMS) > list; 
    ... 

    template< typename T > 
    variant(const T& r) : which_(0), pnt_(0) 
    { 
     typedef meta::find_equivalent_type<const T&, list> found; 
     pnt_ = new(stor_.buf_) ttl::data_holder<typename found::type>(r); 
     which_ = found::index; 
    } 
    ... 
private: 
    template<int N> 
    struct storage 
    { 
     union 
     { 
      ttl::data_holder_base dummy; //hope to satisfy alignment settings 
      char buf_[N]; 
     }; 
    }; 

    int which_; 
    ttl::data_holder_base* pnt_; 
    storage< sizeof(ttl::data_holder<typename list::largest_type>) > stor_; 
    .... 
}; 


struct data_holder_base {}; 

template< typename T > 
struct data_holder : data_holder_base 
{ 
    ... 
    typedef const T& param_type; 

    T d; 
    ... 
    data_holder(param_type d_) : d(d_) {} 
    ... 
}; 

"pnt_"너바나를 가리 킵니다 : 언트는 다음과 같이 정의된다. 나는 그것이 작동이 예제를 확인하는 경우에 대한

template<typename T> 
inline void rebuild() 
{ 
    pnt_ = reinterpret_cast<ttl::data_holder<T>*>(stor_.buf_); 
} 

: 때문에 내가 캐스트를 사용하여 포인터 "pnt_"을 다시 시도 저장되어있는 유형을 알고 있다는 사실. 하지만 새로운 배치 (pnt_ = new(stor_.buf_) ...)가 객체를 stor_.buf_에 배치하는 방법을 모르겠습니다. 개체를 찾으려면 std::distance(&stor_.buf_[0], pnt_)과 같은 것을 저장해야합니까?

pnt_을 다시 얻는 다른 방법이 있습니까?

그 위치 new이 일을 어떻게 정의되는지 때문에

답변

0

배치 newstor_.buf_에서 새 개체를두고 당신에게 마리오 감사드립니다. new에 사용하려는 메모리의 주소를 지정하면 해당 위치에 개체가 생성됩니다. 매우 동일한 주소를 반환하므로 pnt_에 저장된 주소는 stor_.buf_이지만 구성 된 개체 형식이 char* 대신 ttl::data_holder<found::type> 인 주소입니다. 주소가 같기 때문에 사용자가 언급 한 std::distance 값은 항상 0입니다 (호출이 컴파일되는 경우 인수 유형이 다르기 때문에 호출하지 않습니다).

stor_.buf_의 주소도 항상 stor_.dummy의 주소와 같습니다. 당신은이 같은 pnt_을 할당하여 추가 된 코드를 간단하게 만들 수 있습니다 : 당신은 분명히 바로 소켓을 통해 원시 메모리를 복사 한 이후,

pnt_ = &stor_.dummy; 

그러나이 variant 객체의 내부를 고정하는 것은 빙산의 일각에 불과하다 . 변형이 보유하는 값은 이고 주소는이며 내부에 도달 할 방법이 없습니다. 설령 그래도 필요한 주소를 사용할 수 없을 수도 있습니다. variant으로 해결할 주소가 동일한 개체 내의 주소이기 때문에 운 좋게 계산할 수 있습니다. 그러나 무료 저장소에서 메모리를 할당하는 std::string을 고려하십시오. 소켓을 통해 하나를 보내면 다른 쪽에서 쓸모있는 것을 얻을 수 없습니다. 문자 데이터를 전혀 제공하지 못할 수도 있습니다. 대신에 ttl::variant 객체를 직렬화 및 비 직렬화하는 다른 기술을 추구해야합니다. Stack Overflow에 어떻게해야하는지 묻는 질문을 게시 할 수 있습니다.

+0

추가 포인터에 대한 힌트를 제공해 주셔서 감사합니다. 이것은 내 응용 프로그램에서 문제가되지 않습니다. 네, 더미의 주소를 얻는 것이 더 간단하고 못생긴 캐스트는 필요 없어요. 고마워요! – Mario