如何获取当前保留的变量类型,并定义该类型的新变量

时间:2014-09-18 14:07:40

标签: c++ types decltype boost-variant typeid

我有一个类型的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: //...

但我宁愿避免长期陈述,因为我必须多次这样做。

3 个答案:

答案 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;