【发布时间】:2015-01-31 22:42:16
【问题描述】:
出于显而易见的原因,我正在寻找一种在不使用 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->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 :-D 谢谢大家!
【问题讨论】:
标签: c++ pointers map boost-variant