Const Boost变量与地图中的指针类型

时间:2014-12-03 11:24:40

标签: c++ pointers map boost-variant

我正在寻找一种方法来在地图中存储不同类型的指针而不使用void *,原因很明显。我实际上知道编译时指针的类型,这些指针以及它们的类型需要是const,而它们的值需要随时更改。类型总是某种数字类型。

背景 这些指针后面的变量实际上是全局变量,如果发生特定事件,则需要更改这些变量。每个事件都有一个Id,即该映射的第一个成员,它将该变量更改为该事件作为字符串传输的值。

到目前为止,我认为boost :: variant可以解决问题。我是变形的新手,我不知道以下是否会对constness有所作为,但我在阅读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-&gt; varPointer只能初始化一次,只有值可以改变,就像“double * const”一样,所以如果有人在那个指针上乱搞,我会在编译时检查。

谢谢!

更新

经过一些试验和错误后,我发现它确实按预期工作。这就是我迄今为止所做的:

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 :-感谢大家!

1 个答案:

答案 0 :(得分:2)

实际上你可以使用来自boost的访客。

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