2014-12-03 2 views
2

명백한 이유로 void *를 사용하지 않고지도에 다른 유형의 포인터를 저장하는 방법을 찾고 있습니다. 사실 컴파일 타임에 포인터의 유형을 알고 있고 포인터는 해당 유형뿐만 아니라 const 일 필요가 있습니다. 반면 값은 때때로 변경해야합니다. 유형은 항상 일종의 숫자 유형입니다.포인터에 포인터 유형이있는 Const Boost Variant

배경 : 이 포인터 뒤에있는 변수는 실제로 항상 특정 이벤트가 발생하면 변경해야하는 전역 변수입니다. Eachs 이벤트는 해당 맵의 첫 번째 멤버 인 Id를 사용하여 해당 이벤트에 의해 문자열로 전송 된 값으로 변수를 변경합니다.

지금까지 boost :: variant가 트릭을 수행 할 것이라고 생각합니다. 나는 변종에 익숙하지 않다. 그리고 나는 다음이 constness에 관해서 기대했던대로 작동하는지 안다. 그러나 나는 ok 일 것임에 틀림없는 f * cking 매뉴얼을 읽고 나서 생각한다. 주된 문제는 표준 변환을 사용하여 해당 포인터 뒤에 해당 값을 변경하는 방법입니다.

class Data{ 
    public: 
    typedef boost::shared_ptr<Data> Ptr; 
    typedef boost::variant<double*, float*, unsigned int*, int*, unsigned short*, short*, unsigned char*, char*> PodPointerVariant; 
    double factor; 
    const PodPointerVariant varPointer; 

    Data(PodPointerVariant variable) : 
     factor(0.0), 
     varPointer(variable) {} 
} 

std::map<unsigned int, Data::Ptr> dataMap; 
unsigned int intValue; 
float floatValue; 

void main() 
{ 
    intValue = 1; 
    Data::Ptr newEntry(new Data(&intValue)); 
    newEntry->factor = 1.1; 
    dataMap->insert(std::make_pair(1,newEntry)); 

    // Omitted find key and safety if not found... 
    unsigned int eventId = 1; 
    *(dataMap[eventId]->varPointer) = 2.1 * dataMap[1]->factor; // Should be automagically converted to 2 because the pointer is of type unsigned int, but gives a compiler error? I cant dereference that normally. 

} 

이렇게 역 참조하기 쉬운 방법이 있습니까? 어쩌면 방문자 클래스를 사용하고 있을까요? 아니면 다른 것? 이상적으로 Data-> varPointer는 한 번만 초기화되고 "double * const"와 같이 값만 변경 될 수 있습니다. 따라서 누군가가 해당 포인터로 어지럽게 돌아 다니면 컴파일 타임에 확인됩니다.

감사합니다. 내가 예상대로 실제로 작동하는지 알게 시행 착오 후

UPDATE

. 이것은 내가 지금까지 해왔 던 것입니다 :

template<typename U> 
struct DeRefAssignVisitor : public boost::static_visitor<> 
{ 
    U x; 
    double factor; 
    DeRefAssignVisitor(U x, double factor) : x(x), factor(factor) { } 
    template <typename T> 
    void operator()(T* const p) const 
    { 
     *p = (T)(x * factor); 
    } 
}; 

class Data{ 
    public: 
    typedef boost::shared_ptr<Data> Ptr; 
    typedef boost::variant<double * const, float* const, unsigned long* const, long* const, unsigned short* const, short* const, unsigned char* const, char* const, plcbit* const> PodReferenceVariant; 
    double factor; 
    const PodPointerVariant varPointer; 

    Data(PodPointerVariant variable) : 
     factor(0.0), 
     varPointer(variable) {} 

    template <typename T> 
    void setPointerValue(T value) { boost::apply_visitor(DeRefAssignVisitor<T>(value, this->factor), this->varPointer); } 
} 

std::map<unsigned int, Data::Ptr> dataMap; 
unsigned int intValue; 
float floatValue; 

void main() 
{ 
    intValue = 1; 
    floatValue = 2.111; 
    Data::Ptr newEntry(new Data(&intValue)); 
    newEntry->factor = 1.1; 
    dataMap->insert(std::make_pair(1,newEntry)); 

    // Omitted find key and safety if not found... 
    unsigned int eventId = 1; 
    dataMap[eventId]->setPointerValue(floatValue); // Works like a charme: converting compatible types automagically :-) 
} 

템플릿 4TW :-D 모두에게 감사드립니다!

답변

2

실제로 부스트 방문자를 사용할 수 있습니다.

class AssignVisitor : public boost::static_visitor<> 
{ 
public: 
    double x; 
    AssignVisitor(double x) : x(x) { } 
    void operator()(int* p) 
    { 
     *p = (int)x; 
    } 

    void operator()(double* p) 
    { 
     *p = (double)x; 
    } 
    //and so on 
}; 

그리고

boost::apply_visitor(AssignVisitor(2.1 * dataMap[1]->factor), dataMap[eventId]->varPointer); 
+0

나는 그렇게 생각,하지만 난, 방문자 덕분에 매개 변수를 추가하는 방법을 알아낼 couldnt한다. 또한 나는이 쉬운 일이 너무 templated 수 있다고 가정합니다. 나는 그것을 시험해 볼 것이다. –

+0

올바른 방향을 지적 해 주셔서 고맙습니다. 지금 작동하고 있습니다! –