2014-12-03 38 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

相关问题