我有一个类型的boost :: variant变种:
typedef boost::variant< uint8_t, int8_t, uint16_t, int16_t,
uint32_t, int32_t, float, double, std::string > StorageTt;
StorageTt
变量(比如val
)稍后会在我的代码中设置为其中一种存储类型。我想检索val
当前持有的类型来定义同一类型的更多变量。因此,如果val
目前是uint16_t
,我想做类似的事情:
typedef decltype(typeid(val)) StorageTt;
StorageTt new_val = 32.0; // new_val should be a uint16_t
但这会产生一个const type_info类型。我知道我能做到:
switch (val.which()) {
case 0: // uint8_t
case 1: //...
但我宁愿避免长期陈述,因为我必须多次这样做。
答案 0 :(得分:2)
你做不到。变量是句法结构。它们是程序对象的名称。名称仅存在于源代码中。
工作流程如下。首先你写源。然后编译它,运行程序,然后执行一些操作,例如,从boost::variant
对象中检索一个值。此时您无法定义任何名称。没有源,没有名称,没有语法。只有对象。
如果您需要与从变体中检索到的对象类型相同的新对象,那么StorageT new_val(val);
就会创建该对象(新对象隐藏在new_val
中,您可以使用{{1}访问它或boost::get
或其他)。
如果你想对你所拥有的任何变种执行一个动作,并且所有动作看起来都相同,只有它们的类型不同(它们不是相同因为类型不同,它们只是看起来相同),并且你想避免多次写同样的东西,当然模板是你的朋友。 boost::apply_visitor
boost::apply_visitor
是正确的:
template<typename> operator()
答案 1 :(得分:2)
您可以使用带有调用操作员模板的访问者仿函数来执行此类操作:
struct MyVisitor : public boost::static_visitor<>
{
template <typename StorageT>
void operator()(const StorageT&) const
{
StorageT new_val = 32; // declare variable with same type
doSomethingWith(new_val); // do something with it
}
};
将其应用于变体val
,如下所示:
boost::apply_visitor(MyVisitor(), val);
参考:
我不知道用C ++ 14泛型lambda替换仿函数的方法。
答案 2 :(得分:0)
使用复制构造函数应该可以工作:
// construct object of same type as val
StorageT new_val(val);
boost::get(new_val) = 32.0;