2014-12-03 37 views
2

我正在尋找一種方法來在地圖中存儲不同類型的指針,而不使用void *,原因很明顯。我實際上知道編譯時指針的類型,這些指針以及它們的類型需要是const的,而它們的值需要從時間變爲時間。類型總是某種數字類型。Const Boost Variant在地圖中指針類型

背景: 這些指針後面的變量實際上總是全局變量,如果發生特定事件,它們需要更改。每個事件都有一個Id,它是該映射的第一個成員,它將變量更改爲由該事件作爲字符串傳輸的值。

到目前爲止,我認爲boost :: variant會做到這一點。我對變體很陌生,我不知道以下內容是否會按照預期的方式工作,但是我在閱讀完fke手冊後認爲它應該沒問題。主要問題仍然是如何使用標準轉換來更改該指針後面的值:

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

我也這樣想,但我不能弄清楚如何將參數添加到訪客,謝謝。另外我假設這個簡單的任務也可以模板化。我會嘗試一下。 – 2014-12-03 12:12:45

+0

感謝您指出正確的方向,我現在就開始工作! – 2014-12-09 12:24:36

相關問題