2014-12-03 7 views
2

Я ищу способ хранения различных типов указателей на карте без использования void * по понятным причинам. Я действительно знаю типы указателей во время компиляции, и эти указатели, а также их типы должны быть const, а их значения должны меняться от времени к разу. Типы всегда представляют собой своего рода числовые типы.Const Boost Variant с типами указателей на карте

Справочная информация: Переменные, лежащие за этими указателями, фактически являются глобальными переменными, которые необходимо изменить, если происходит определенное событие. Каждое событие имеет идентификатор, первый член этой карты, который изменяет переменную на значение, переданное этим событием в виде строки.

До сих пор я думаю, что boost :: variant будет делать трюк. Я новичок в варианте, и я не знаю, будет ли работать над ожиданием относительно константы, но я предполагаю, что после чтения руководства 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

Фактически вы можете использовать посетителей от 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); 
+0

Я хоть так, но я не мог понять, как добавить параметр к посетителю, спасибо. Также я предполагаю, что эту легкую задачу можно было бы также задумать. Я попробую. –

+0

Спасибо за указание в правильном направлении, я получил его сейчас! –

 Смежные вопросы

  • Нет связанных вопросов^_^